Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: eggert/tz
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2023d
Choose a base ref
...
head repository: eggert/tz
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2024a
Choose a head ref

Commits on Dec 30, 2023

  1. Fix localtime.c bug: America/Ciudad_Juarez in 2422

    Problem reported by Gilmore Davidson in:
    https://mm.icann.org/pipermail/tz/2023-December/033392.html
    * NEWS: Mention this.
    * localtime.c (tzparse): Use a window that is one year longer,
    for the same reason zic.c uses a window like that.
    * private.h (years_of_observations): Move here ...
    * zic.c (outzone): ... from here.
    eggert committed Dec 30, 2023
    Copy the full SHA
    284ebde View commit details

Commits on Dec 31, 2023

  1. Comics update

    Add xkcd’s “Daylight Saving Choice”, “Date Line” and “DateTime”, along
    with today’s Frazz and FoxTrot.  Remove Dilbert, which had a bad link.
    eggert committed Dec 31, 2023
    Copy the full SHA
    d6a94fe View commit details
  2. Reformat music section

    * tz-art.html (Music): Reformat more compactly, using an
    unnumbered list rather than a table.
    eggert committed Dec 31, 2023
    Copy the full SHA
    322abaa View commit details

Commits on Jan 2, 2024

  1. Avoid expr in tzselect

    * tzselect.ksh: Rewrite to not use the expr command.
    Various implementations have problems or dump core given unusual
    inputs, so to avoid these issues use awk or sh (which we need to
    use anyway) instead of using expr.
    eggert committed Jan 2, 2024
    Copy the full SHA
    d03bc3a View commit details
  2. Avoid sed in tzselect

    * tzselect.ksh: Rewrite to not use the sed command.
    It’s used only in one place, and awk can do it;
    this removes a dependency of tzselect on sed.
    eggert committed Jan 2, 2024
    Copy the full SHA
    d4c4422 View commit details
  3. Avoid pwd in tzselect when developing

    * tzselect.ksh: Rewrite to not use the pwd command when developing,
    except on ancient shells where PWD does not work.
    This removes a dependency when developing on non-ancient platforms.
    eggert committed Jan 2, 2024
    Copy the full SHA
    325e4ef View commit details

Commits on Jan 4, 2024

  1. Name two constants in zic.c

    * zic.c (YEAR_32BIT_MIN, YEAR_32BIT_MAX): New constants.
    (outzone): Use them instead of integer literals.
    eggert committed Jan 4, 2024
    Copy the full SHA
    f83d3a3 View commit details
  2. Remove support for "min" in Rule lines

    It has not been needed for decades in TZDB, and has not really
    worked for even longer than that.  If the user specifies
    FROM == "min", warn and use 1900 instead.
    * NEWS, zic.8: Document this.
    * zic.c (struct rule): Remove r_lowasnum member, since they
    are always effectively numbers now.  All uses removed.
    (begin_years): Remove "maximum".
    (end_years): Remove "minimum".
    (rulesub): Diagnose use of "min" for FROM.  Omit
    no-longer-possible cases.
    (outzone): Do not worry about DST into the indefinite past.
    eggert committed Jan 4, 2024
    Copy the full SHA
    321a49c View commit details
  3. Copy the full SHA
    95fa1a4 View commit details

Commits on Jan 5, 2024

  1. Improve tzalloc etc. man page

    This attempts to address Guy Harris’s comments:
    https://mm.icann.org/pipermail/tz/2024-January/033418.html
    and cleans up other stuff in the neighborhood.
    * newtzset.3: Use italics as per current Linux man page style.
    Reword for clarity.  Refer to POSIX.1-2017 specifically when the
    next POSIX may well differ.
    (RETURN VALUE, ERRORS): New sections.
    eggert committed Jan 5, 2024
    Copy the full SHA
    5a43b0d View commit details

Commits on Jan 8, 2024

  1. Automate copying of leap-seconds.list

    * Makefile (leaplist_URI, leaplist_TZ, EXTRACT_AUTHOR): New macros.
    (fetch-leap-seconds.list, commit-leap-seconds.list):
    New phony rules, for maintainer use.
    * NEWS, leapseconds.awk: Mention this.
    eggert committed Jan 8, 2024
    Copy the full SHA
    27b4d76 View commit details

Commits on Jan 9, 2024

  1. make commit-leap-seconds.list

    Christian Bizouard authored and eggert committed Jan 9, 2024
    Copy the full SHA
    cb72e39 View commit details
  2. Toronto 1947/1949 switched at 02:00 not 00:00

    * NEWS: Mention this.
    * northamerica (Toronto): Simplify 1945/1973 rules to reflect the
    fact that Toronto’s transitions in 1947/1949 were at 02:00 not
    00:00 (thanks to Chris Walton).
    eggert committed Jan 9, 2024
    Copy the full SHA
    56c1580 View commit details

Commits on Jan 10, 2024

  1. Miquelon 1911 transition was June 15 not May 15

    I found a new source: Société Française de Physique, Recueil de
    constantes physiques (1913), page 752 (errata and addenda), 18b.
    It agrees with Shanks about the adoption of standard time in
    French possessions, except for Miquelon.  Prefer it to Shanks.
    Also, fill in day of month (e.g., “Jan 1” not “Jan”) for other
    transitions, since the source seems careful about the day.
    * NEWS: Mention this.
    * africa (Africa/Ndjamena, Africa/Abidjan):
    * australasia (Pacific/Gambier, Pacific/Marquesas, Pacific/Tahiti)
    (Pacific/Guadalcanal):
    * northamerica (America/Martinique):
    * southamerica (America/Cayenne):
    Fill in day of month as 1.  This does not change the transitions;
    it’s merely documentation.
    * northamerica (America/Miquelon): 1911 transition was Jun 15,
    not May 15.
    eggert committed Jan 10, 2024
    Copy the full SHA
    e6b5683 View commit details
  2. Don’t mention ftp.nist.gov

    * leapseconds.awk: Don’t mention ftp.nist.gov in comments,
    as the site no longer seems to be available.
    (Problem reported by PoolMUC.)
    eggert committed Jan 10, 2024
    Copy the full SHA
    f927f6e View commit details
  3. "m" now abbreviates both "maximum" and "minimum"

    * zishrink.awk: Add comment about "m".
    eggert committed Jan 10, 2024
    Copy the full SHA
    4005260 View commit details

Commits on Jan 11, 2024

  1. Shrink tzdata.zi a bit more if vanguard

    * zishrink.awk (process_input_line): In vanguard format,
    use shorter forms "m" for "max" and (the never-used) "min".
    eggert committed Jan 11, 2024
    Copy the full SHA
    1ca031c View commit details
  2. Simplify zishrink.awk

    * zishrink.awk (process_input_line): Simplify by
    omitting an optimization that is no longer needed.
    eggert committed Jan 11, 2024
    Copy the full SHA
    05588b6 View commit details
  3. Shrink lines by class

    * zishrink.awk (process_input_line): Output rule lines first, then
    zone lines, then link lines.  Although this doesn’t change the set
    of output lines, it should makes the output a bit more compressible.
    eggert committed Jan 11, 2024
    Copy the full SHA
    b848dce View commit details
  4. Sort zones by name when shrinking

    * zishrink.awk (output_saved_lines): Sort zones by name if
    using Gawk.
    eggert committed Jan 11, 2024
    Copy the full SHA
    77e6d7f View commit details
  5. Sort links by dest when shrinking vanguard

    * zishrink.awk (process_input_line, output_saved_lines):
    Sort links by destination name if vanguard and using Awk.
    eggert committed Jan 11, 2024
    Copy the full SHA
    4238791 View commit details

Commits on Jan 12, 2024

  1. Draft next POSIX has tm_gmtoff, tm_zone

    * private.h (TM_GMTOFF, TM_ZONE): Treat draft next POSIX like
    glibc etc., since it requires tm_gmtoff and tm_zone.
    eggert committed Jan 12, 2024
    Copy the full SHA
    b4ec327 View commit details

Commits on Jan 13, 2024

  1. For strftime %z, use tm_gmtoff if available

    Problem and draft patch reported by Dag-Erling Smørgrav in:
    https://mm.icann.org/pipermail/tz/2024-January/033488.html
    * NEWS: Mention this.
    * localtime.c (EXTERN_TIMEOFF): Default to static.
    (timeoff): Use EXTERN_TIMEOFF to declare; this is easier to read.
    * private.h (EXTERN_TIMEOFF): New macro.
    (timeoff): Define to tz_private_timeoff if it’s not public but
    strftime needs it anyway.  Declare if we define it as extern.
    * strftime.c (_fmt): If TM_GMTOFF is available, use timeoff
    rather than mktime to determine %z.  Do not worry about UNINIT_TRAP
    since we are now using a more-generous reading of POSIX.
    eggert committed Jan 13, 2024
    1
    Copy the full SHA
    a707253 View commit details
  2. Document strftime struct tm member usage

    * NEWS: Mention this.
    * newstrftime.3: Document which struct tm members
    affect which conversion specs.
    eggert committed Jan 13, 2024
    Copy the full SHA
    fc7b8b6 View commit details

Commits on Jan 14, 2024

  1. More strftime doc improvements

    (Problems reported by Steve Summit.)
    * NEWS: Mention this.
    * newstrftime.3: Add portability advice.  Say tzset is called.
    eggert committed Jan 14, 2024
    Copy the full SHA
    b7f926f View commit details
  2. Asia/Ho_Chi_Minh 1945-09 Source added

    A new source for the transition of Asia/Ho_Chi_Minh and Asia/Hanoi
    from +09 to +07 was found.
    
    The source is Việt Nam Dân Quốc Công Báo (Official Journal of the People
    Republic of Viet Nam). Original text and translation:
    
    Bộ-trưởng bộ Nội-vụ
    Minister of Ministry of Internal Affairs
    
    Chiểu chi nghị-định cựu Toàn-Quyền Đông-Dương ngày 29 tháng 3 năm 1945
    ấn định giờ chính thức ở Đông-Dương,
    Based on the decision of the former Governor-General of the (French)
    Indochina on the 29th of March, 1945, that dictated the official
    timezone in Indochina,
    
    Nghị-Định Decided
    
    Điều thứ nhất: Trong toàn cõi nước Việt-Nam, giờ chính thức do nghị định
    ngày 29 tháng 3 năm 1945 ấn định, sẽ lui lại hai giờ, kể từ 24 giờ, ngày
    mồng 1 tháng 9 năm 1945.
    Article 1: In the whole Viet-Nam, the official timezone as dictated by
    decision on the 29th of March 1945, would move back 2 hours, effective
    at 24:00 on the 1st of September 1945
    
    Điều thứ hai: Nghị-định cựu Toàn-Quyền Đông-Dương ngày 29 tháng 3 năm
    1945 kể trên từ nay sẽ bãi bỏ.
    Article 2: The Decision on the 29 of March 1945 of the former
    Governor-General of the Indochina would be canceled from now on.
    
    Hà-nội ngày mồng 1 tháng 9 năm 1945
    Đoàn Trần Công Danh via tz authored and eggert committed Jan 14, 2024
    Copy the full SHA
    893c20b View commit details
  3. Improve recent Vietnam doc

    * asia (Asia/Ho_Chi_Minh): Improve recent doc and insert
    explicit time (this does not change TZif file).
    eggert committed Jan 14, 2024
    Copy the full SHA
    16495d6 View commit details

Commits on Jan 16, 2024

  1. Update Matthews & Vincent URI

    * northamerica: Update URI (thanks to Brian Inglis).
    eggert committed Jan 16, 2024
    Copy the full SHA
    8459570 View commit details

Commits on Jan 19, 2024

  1. Kazakhstan unifies on UTC+5 beginning 2024-03-01.

    * NEWS: Mention this.
    * asia (Asia/Almaty, Asia/Qostanay): Switch from UTC+6 to UTC+5
    beginning 2024-03-01 00:00.
    timparenti committed Jan 19, 2024
    Copy the full SHA
    95a16c8 View commit details
  2. Pacify ‘make check’ for Kazakhstan changes

    * zonenow.tab (Asia/Almaty): New zone to pacify ‘make check_now’.
    We can remove this zone from zonenow.tab on 2024-03-01, because
    it is identical to Asia/Dhaka from then on.
    eggert committed Jan 19, 2024
    Copy the full SHA
    608c13d View commit details
  3. Fix typo in checknow.awk diagnostic

    * checknow.awk: The diagnostic is about zonenow.tab, not
    a (nonexistent) checknow.tab.
    eggert committed Jan 19, 2024
    Copy the full SHA
    39bfdc7 View commit details
  4. Update Kazakhstan region comments

    * asia (Asia/Almaty): Update list of Kazakhstan administrative
    regions and cities in commentary, as they added some in 2022.
    eggert committed Jan 19, 2024
    Copy the full SHA
    9a43fed View commit details
  5. Add Kazakhstan PM’s decision

    * asia: Add link to prime minister’s decision
    (thanks to Zhanbolat Raimbekov).
    eggert committed Jan 19, 2024
    Copy the full SHA
    1fe9702 View commit details
  6. Asia/Ho_Chi_Minh: Correct 1955 transition

    While we're at it, updating source for 1959 transition.
    
    Ordinance 46 of 1955, first article read:
    
    Kể từ ngày mồng 1 tháng bảy năm 1955, giờ chính-thức ở Việt-nam là giờ
    của thời đạo thứ bảy.
    From the 1955-07-01, the offical time in Vietnam is the time of
    the +07 timezone.
    
    ... lùi chậm sáu mươi phút, trong đêm hôm 30 tháng sáu năm 1955,
    rạng mặt ngày mồng 1 tháng bảy năm 1955 lúc một giờ sáng.
    ... move back 60 minutes, in the night of 1955-06-30, early morning
    of 1955-07-01 at 1AM.
    
    Decree 362-TTP of 1959, first article read:
    
    Kể từ ngày mồng 1 tháng giêng d.l. năm 1960, giờ chánh thức và pháp định
    ở Việt-nam được đặt nhanh hơn giờ của thời-đạo thứ bảy sáu mươi phút.
    From the 1st of January 1960, de facto and de jure time in Vietnam will
    be faster than the +07 timezone, 60 minutes.
    
    ... vặn nhanh lên sáu mươi phút lúc 23 giờ đêm hôm 31 tháng chạp d.l.
    năm 1959, rạng mặt ngày mồng 1 tháng giêng d.l. năm 1960.
    ... fast forward 60 minutes at 23:00 of the night of 1959-12-31, early
    morning of 1960-01-01.
    sgn authored and eggert committed Jan 19, 2024
    Copy the full SHA
    2cbd39c View commit details

Commits on Jan 20, 2024

  1. Update ISO 3166-2:KZ codes for Kazakhstan

    * asia: Use new numeric ISO 3166-2:KZ codes.
    timparenti committed Jan 20, 2024
    Copy the full SHA
    7de0bfb View commit details
  2. Copy the full SHA
    f481c61 View commit details

Commits on Jan 22, 2024

  1. Update some tz-link links

    * tz-link.html: Update some citations and remove some that
    no longer work.
    eggert committed Jan 22, 2024
    Copy the full SHA
    e9f12c3 View commit details
  2. Mention zonenow.tab in “Theory”

    * theory.html (Timezone identifiers): Mention zonenow.tab.
    eggert committed Jan 22, 2024
    Copy the full SHA
    f295cc1 View commit details
  3. Fix NEWS typo for strftime

    * NEWS: %s, not %z (thanks to Dag-Erling Smørgrav).
    eggert committed Jan 22, 2024
    Copy the full SHA
    b3d4dbb View commit details

Commits on Jan 24, 2024

  1. Update link to Palestine MTIT

    * tz-link.html: Update link
    eggert committed Jan 24, 2024
    Copy the full SHA
    f4c6e5f View commit details

Commits on Jan 25, 2024

  1. Palestine springs forward a week later after Ramadan

    Palestine’s cabinet announced changes for 2024 and 2025
    (thanks to Heba Hamad).
    * NEWS: Mention this.
    * asia (Palestine): Adjust 2024 and 2025 to match government
    announcement.  Guess the second Saturday after Ramadan for later
    transitions.
    eggert committed Jan 25, 2024
    Copy the full SHA
    23e7cfa View commit details

Commits on Jan 28, 2024

  1. Document POSIX versions more carefully

    Since the next POSIX will require support for TZDB Zone names in the
    TZ environment variable, be more careful about phrases like
    “POSIX-like TZ strings” in comments and documentation.  Call them
    “POSIX.1-2017-like TZ strings” instead, to make it clearer that
    they’re the traditional POSIX form like TZ='GMT0BST,M3.5.0/1,M10.5.0'
    instead of the TZDB form like TZ='Europe/London'.
    eggert committed Jan 28, 2024
    Copy the full SHA
    2903b9a View commit details
  2. Copy the full SHA
    983d3ef View commit details
  3. Copy the full SHA
    9740ab1 View commit details

Commits on Jan 30, 2024

  1. Improve Czechoslovakia commentary

    * europe: Improve commentary for Czechoslovakia in 1918 and 1946.
    (Thanks to Ivan Benovic.)
    eggert committed Jan 30, 2024
    Copy the full SHA
    619fcf0 View commit details

Commits on Feb 1, 2024

  1. Streamline tz-link a bit

    * tz-link.html: Defer to the Timezone Boundary Builder web page
    for a list of libraries that use it, as its list is larger and
    better-maintained than ours. Mention how old the Manifold map is.
    Mention WRC 2023 resolution on leap seconds.
    eggert committed Feb 1, 2024
    Copy the full SHA
    75c9e59 View commit details
  2. Update a few stale links

    * theory.html, tz-art.html: Update stale links and normalize
    some punctuation and white space.
    eggert committed Feb 1, 2024
    Copy the full SHA
    85a0aad View commit details
  3. Copy the full SHA
    a97e920 View commit details
  4. Release 2024a

    * NEWS: Increase version to 2024a.
    eggert committed Feb 1, 2024
    Copy the full SHA
    380c07c View commit details
Showing with 1,091 additions and 880 deletions.
  1. +42 −11 Makefile
  2. +68 −0 NEWS
  3. +6 −2 africa
  4. +109 −65 asia
  5. +9 −5 australasia
  6. +1 −1 checknow.awk
  7. +1 −1 etcetera
  8. +27 −2 europe
  9. +119 −254 leap-seconds.list
  10. +4 −7 leapseconds.awk
  11. +18 −13 localtime.c
  12. +150 −2 newstrftime.3
  13. +99 −65 newtzset.3
  14. +19 −10 northamerica
  15. +28 −2 private.h
  16. +4 −1 southamerica
  17. +4 −3 strftime.c
  18. +21 −16 theory.html
  19. +181 −231 tz-art.html
  20. +41 −56 tz-link.html
  21. +15 −13 tzfile.5
  22. +3 −3 tzfile.h
  23. +28 −15 tzselect.ksh
  24. +7 −16 zic.8
  25. +19 −52 zic.c
  26. +65 −33 zishrink.awk
  27. +3 −1 zonenow.tab
53 changes: 42 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ DATAFORM= main

LOCALTIME= Factory

# The POSIXRULES macro controls interpretation of POSIX-like TZ
# The POSIXRULES macro controls interpretation of POSIX-2017.1-like TZ
# settings like TZ='EET-2EEST' that lack DST transition rules.
# If POSIXRULES is '-', no template is installed; this is the default.
# Any other value for POSIXRULES is obsolete and should not be relied on, as:
@@ -274,7 +274,7 @@ LDLIBS=
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
# the default is system-supplied, typically "/usr/lib/locale"
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
# DST transitions for POSIX-style TZ strings lacking them,
# DST transitions for POSIX.1-2017-style TZ strings lacking them,
# in the usual case where POSIXRULES is '-'. If not specified,
# TZDEFRULESTRING defaults to US rules for future DST transitions.
# This mishandles some past timestamps, as US DST rules have changed.
@@ -340,9 +340,10 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# guess TM_GMTOFF from other macros; define NO_TM_GMTOFF to suppress this.
# Similarly, if your system has a "zone abbreviation" field, define
# -DTM_ZONE=tm_zone
# and define NO_TM_ZONE to suppress any guessing. Although these two fields
# not required by POSIX, a future version of POSIX is planned to require them
# and they are widely available on GNU/Linux and BSD systems.
# and define NO_TM_ZONE to suppress any guessing.
# Although these two fields are not required by POSIX.1-2017,
# POSIX 202x/D4 requires them and they are widely available
# on GNU/Linux and BSD systems.
#
# The next batch of options control support for external variables
# exported by tzcode. In practice these variables are less useful
@@ -352,7 +353,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# # -DHAVE_TZNAME=0 # do not support "tzname"
# # -DHAVE_TZNAME=1 # support "tzname", which is defined by system library
# # -DHAVE_TZNAME=2 # support and define "tzname"
# # to the "CFLAGS=" line. "tzname" is required by POSIX 1988 and later.
# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later.
# # If not defined, the code attempts to guess HAVE_TZNAME from other macros.
# # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause
# # crashes when combined with some platforms' standard libraries,
@@ -362,8 +363,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# # -DUSG_COMPAT=0 # do not support
# # -DUSG_COMPAT=1 # support, and variables are defined by system library
# # -DUSG_COMPAT=2 # support and define variables
# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by
# # Unix Systems Group code and are required by POSIX 2008 (with XSI) and later.
# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by Unix
# # Systems Group code and are required by POSIX.1-2008 and later (with XSI).
# # If not defined, the code attempts to guess USG_COMPAT from other macros.
# #
# # To support the external variable "altzone", add
@@ -427,7 +428,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \

# The name of a POSIX-like library archiver, its flags, C compiler,
# linker flags, and 'make' utility. Ordinarily the defaults suffice.
# The commented-out values are the defaults specified by POSIX 202x/D3.
# The commented-out values are the defaults specified by POSIX.1-202x/D4.
#AR = ar
#ARFLAGS = -rv
#CC = c17
@@ -439,6 +440,12 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \

LEAPSECONDS=

# Where to fetch leap-seconds.list from.
leaplist_URI = \
https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list
# The file is generated by the IERS Earth Orientation Centre, in Paris.
leaplist_TZ = Europe/Paris

# The zic command and its arguments.

zic= ./zic
@@ -471,7 +478,8 @@ AWK= awk
# is typically nicer if it works.
KSHELL= /bin/bash

# Name of curl <https://curl.haxx.se/>, used for HTML validation.
# Name of curl <https://curl.haxx.se/>, used for HTML validation
# and to fetch leap-seconds.list from upstream.
CURL= curl

# Name of GNU Privacy Guard <https://gnupg.org/>, used to sign distributions.
@@ -718,6 +726,28 @@ leapseconds: $(LEAP_DEPS)
-f leapseconds.awk leap-seconds.list >$@.out
mv $@.out $@
# Awk script to extract a Git-style author from leap-seconds.list comments.
EXTRACT_AUTHOR = \
author_line { sub(/^.[[:space:]]*/, ""); \
sub(/:[[:space:]]*/, " <"); \
printf "%s>\n", $$0; \
success = 1; \
exit \
} \
/Questions or comments to:/ { author_line = 1 } \
END { exit !success }
# Fetch leap-seconds.list from upstream.
fetch-leap-seconds.list:
$(CURL) -OR $(leaplist_URI)
# Fetch leap-seconds.list from upstream and commit it to the local repository.
commit-leap-seconds.list: fetch-leap-seconds.list
author=$$($(AWK) '$(EXTRACT_AUTHOR)' leap-seconds.list) && \
date=$$(TZ=$(leaplist_TZ) stat -c%y leap-seconds.list) && \
git commit --author="$$author" --date="$$date" -m'make $@' \
leap-seconds.list
# Arguments to pass to submakes of install_data.
# They can be overridden by later submake arguments.
INSTALLARGS = \
@@ -1315,7 +1345,8 @@ zic.o: private.h tzfile.h tzdir.h version.h
.PHONY: ALL INSTALL all
.PHONY: check check_mild check_time_t_alternatives
.PHONY: check_web check_zishrink
.PHONY: clean clean_misc dummy.zd force_tzs
.PHONY: clean clean_misc commit-leap-seconds.list dummy.zd
.PHONY: fetch-leap-seconds.list force_tzs
.PHONY: install install_data maintainer-clean names
.PHONY: posix_only posix_right public
.PHONY: rearguard_signatures rearguard_signatures_version
68 changes: 68 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
News for the tz database

Release 2024a - 2024-02-01 09:28:56 -0800

Briefly:
Kazakhstan unifies on UTC+5 beginning 2024-03-01.
Palestine springs forward a week later after Ramadan.
zic no longer pretends to support indefinite-past DST.
localtime no longer mishandles Ciudad Juárez in 2422.

Changes to future timestamps

Kazakhstan unifies on UTC+5. This affects Asia/Almaty and
Asia/Qostanay which together represent the eastern portion of the
country that will transition from UTC+6 on 2024-03-01 at 00:00 to
join the western portion. (Thanks to Zhanbolat Raimbekov.)

Palestine springs forward a week later than previously predicted
in 2024 and 2025. (Thanks to Heba Hamad.) Change spring-forward
predictions to the second Saturday after Ramadan, not the first;
this also affects other predictions starting in 2039.

Changes to past timestamps

Asia/Ho_Chi_Minh's 1955-07-01 transition occurred at 01:00
not 00:00. (Thanks to Đoàn Trần Công Danh.)

From 1947 through 1949, Toronto's transitions occurred at 02:00
not 00:00. (Thanks to Chris Walton.)

In 1911 Miquelon adopted standard time on June 15, not May 15.

Changes to code

The FROM and TO columns of Rule lines can no longer be "minimum"
or an abbreviation of "minimum", because TZif files do not support
DST rules that extend into the indefinite past - although these
rules were supported when TZif files had only 32-bit data, this
stopped working when 64-bit TZif files were introduced in 1995.
This should not be a problem for realistic data, since DST was
first used in the 20th century. As a transition aid, FROM columns
like "minimum" are now diagnosed and then treated as if they were
the year 1900; this should suffice for TZif files on old systems
with only 32-bit time_t, and it is more compatible with bugs in
2023c-and-earlier localtime.c. (Problem reported by Yoshito
Umaoka.)

localtime and related functions no longer mishandle some
timestamps that occur about 400 years after a switch to a time
zone with a DST schedule. In 2023d data this problem was visible
for some timestamps in November 2422, November 2822, etc. in
America/Ciudad_Juarez. (Problem reported by Gilmore Davidson.)

strftime %s now uses tm_gmtoff if available. (Problem and draft
patch reported by Dag-Erling Smørgrav.)

Changes to build procedure

The leap-seconds.list file is now copied from the IERS instead of
from its downstream counterpart at NIST, as the IERS version is
now in the public domain too and tends to be more up-to-date.
(Thanks to Martin Burnicki for liaisoning with the IERS.)

Changes to documentation

The strftime man page documents which struct tm members affect
which conversion specs, and that tzset is called. (Problems
reported by Robert Elz and Steve Summit.)


Release 2023d - 2023-12-21 20:02:24 -0800

Briefly:
8 changes: 6 additions & 2 deletions africa
Original file line number Diff line number Diff line change
@@ -30,6 +30,10 @@
# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
# https://www.jstor.org/stable/1774359
#
# For the 1911/1912 establishment of standard time in French possessions, see:
# Société Française de Physique, Recueil de constantes physiques (1913),
# page 752, 18b.
#
# European-style abbreviations are commonly used along the Mediterranean.
# For sub-Saharan Africa abbreviations were less standardized.
# Previous editions of this database used WAT, CAT, SAT, and EAT
@@ -113,7 +117,7 @@ Zone Atlantic/Cape_Verde -1:34:04 - LMT 1912 Jan 01 2:00u # Praia

# Chad
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena
Zone Africa/Ndjamena 1:00:12 - LMT 1912 Jan 1 # N'Djamena
1:00 - WAT 1979 Oct 14
1:00 1:00 WAST 1980 Mar 8
1:00 - WAT
@@ -139,7 +143,7 @@ Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena
# Inaccessible, Nightingale: uninhabited

# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Abidjan -0:16:08 - LMT 1912
Zone Africa/Abidjan -0:16:08 - LMT 1912 Jan 1
0:00 - GMT

###############################################################################
174 changes: 109 additions & 65 deletions asia
Original file line number Diff line number Diff line change
@@ -2457,18 +2457,33 @@ Zone Asia/Amman 2:23:44 - LMT 1931
# effective December 21st, 2018....
# http://adilet.zan.kz/rus/docs/P1800000817 (russian language).

# From Zhanbolat Raimbekov (2024-01-19):
# Kazakhstan (all parts) switching to UTC+5 on March 1, 2024
# https://www.gov.kz/memleket/entities/mti/press/news/details/688998?lang=ru
# [in Russian]
# (2024-01-20): https://primeminister.kz/ru/decisions/19012024-20
#
# From Alexander Krivenyshev (2024-01-19):
# According to a different news and the official web site for the Ministry of
# Trade and Integration of the Republic of Kazakhstan:
# https://en.inform.kz/news/kazakhstan-to-switch-to-single-hour-zone-mar-1-54ad0b/

# Zone NAME STDOFF RULES FORMAT [UNTIL]
#
# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA,
# KZ-KAR, KZ-SEV, KZ-PAV, and KZ-YUZ.
# This includes Abai/Abay (ISO 3166-2 code KZ-10), Aqmola/Akmola (KZ-11),
# Almaty (KZ-19), Almaty city (KZ-75), Astana city (KZ-71),
# East Kazkhstan (KZ-63), Jambyl/Zhambyl (KZ-31), Jetisu/Zhetysu (KZ-33),
# Karaganda (KZ-35), North Kazakhstan (KZ-59), Pavlodar (KZ-55),
# Shyumkent city (KZ-79), Turkistan (KZ-61), and Ulytau (KZ-62).
Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata
5:00 - +05 1930 Jun 21
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s
6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s
6:00 - +06
# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
6:00 - +06 2024 Mar 1 0:00
5:00 - +05
# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-43)
Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
5:00 - +05 1981 Apr 1
@@ -2481,8 +2496,7 @@ Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2
5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
6:00 - +06 2018 Dec 21 0:00
5:00 - +05
#
# Qostanay (aka Kostanay, Kustanay) (KZ-KUS)
# Qostanay (aka Kostanay, Kustanay) (KZ-39)
# The 1991/2 rules are unclear partly because of the 1997 Turgai
# reorganization.
Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2
@@ -2493,9 +2507,9 @@ Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2
5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s
4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
6:00 - +06

# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
6:00 - +06 2024 Mar 1 0:00
5:00 - +05
# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-15)
Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
5:00 - +05 1981 Apr 1
@@ -2505,7 +2519,7 @@ Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2
4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
5:00 - +05
# Mangghystaū (KZ-MAN)
# Mangghystaū (KZ-47)
# Aqtau was not founded until 1963, but it represents an inhabited region,
# so include timestamps before 1963.
Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2
@@ -2517,7 +2531,7 @@ Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2
5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s
4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s
5:00 - +05
# Atyraū (KZ-ATY) is like Mangghystaū except it switched from
# Atyraū (KZ-23) is like Mangghystaū except it switched from
# +04/+05 to +05/+06 in spring 1999, not fall 1994.
Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2
3:00 - +03 1930 Jun 21
@@ -2528,7 +2542,7 @@ Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2
5:00 RussiaAsia +05/+06 1999 Mar 28 2:00s
4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s
5:00 - +05
# West Kazakhstan (KZ-ZAP)
# West Kazakhstan (KZ-27)
# From Paul Eggert (2016-03-18):
# The 1989 transition is from USSR act No. 227 (1989-03-14).
Zone Asia/Oral 3:25:24 - LMT 1924 May 2 # or Ural'sk
@@ -3430,19 +3444,26 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# ... winter time will begin in Palestine from Saturday 10-28-2023,
# 02:00 AM by 60 minutes back.
#
# From Paul Eggert (2023-03-22):
# From Heba Hamad (2024-01-25):
# the summer time for the years 2024,2025 will begin in Palestine
# from Saturday at 02:00 AM by 60 minutes forward as shown below:
# year date
# 2024 2024-04-20
# 2025 2025-04-12
#
# From Paul Eggert (2024-01-25):
# For now, guess that spring and fall transitions will normally
# continue to use 2022's rules, that during DST Palestine will switch
# to standard time at 02:00 the last Saturday before Ramadan and back
# to DST at 02:00 the first Saturday after Ramadan, and that
# to DST at 02:00 the second Saturday after Ramadan, and that
# if the normal spring-forward or fall-back transition occurs during
# Ramadan the former is delayed and the latter advanced.
# To implement this, I predicted Ramadan-oriented transition dates for
# 2023 through 2086 by running the following program under GNU Emacs 28.2,
# 2026 through 2086 by running the following program under GNU Emacs 29.2,
# with the results integrated by hand into the table below.
# Predictions after 2086 are approximated without Ramadan.
#
# (let ((islamic-year 1444))
# (let ((islamic-year 1447))
# (require 'cal-islam)
# (while (< islamic-year 1510)
# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
@@ -3451,6 +3472,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# (while (/= saturday (mod (setq a (1- a)) 7)))
# (while (/= saturday (mod b 7))
# (setq b (1+ b)))
# (setq b (+ 7 b))
# (setq a (calendar-gregorian-from-absolute a))
# (setq b (calendar-gregorian-from-absolute b))
# (insert
@@ -3501,84 +3523,84 @@ Rule Palestine 2021 only - Oct 29 1:00 0 -
Rule Palestine 2022 only - Mar 27 0:00 1:00 S
Rule Palestine 2022 2035 - Oct Sat<=30 2:00 0 -
Rule Palestine 2023 only - Apr 29 2:00 1:00 S
Rule Palestine 2024 only - Apr 13 2:00 1:00 S
Rule Palestine 2025 only - Apr 5 2:00 1:00 S
Rule Palestine 2024 only - Apr 20 2:00 1:00 S
Rule Palestine 2025 only - Apr 12 2:00 1:00 S
Rule Palestine 2026 2054 - Mar Sat<=30 2:00 1:00 S
Rule Palestine 2036 only - Oct 18 2:00 0 -
Rule Palestine 2037 only - Oct 10 2:00 0 -
Rule Palestine 2038 only - Sep 25 2:00 0 -
Rule Palestine 2039 only - Sep 17 2:00 0 -
Rule Palestine 2039 only - Oct 22 2:00 1:00 S
Rule Palestine 2039 2067 - Oct Sat<=30 2:00 0 -
Rule Palestine 2040 only - Sep 1 2:00 0 -
Rule Palestine 2040 only - Oct 13 2:00 1:00 S
Rule Palestine 2040 only - Oct 20 2:00 1:00 S
Rule Palestine 2040 2067 - Oct Sat<=30 2:00 0 -
Rule Palestine 2041 only - Aug 24 2:00 0 -
Rule Palestine 2041 only - Sep 28 2:00 1:00 S
Rule Palestine 2041 only - Oct 5 2:00 1:00 S
Rule Palestine 2042 only - Aug 16 2:00 0 -
Rule Palestine 2042 only - Sep 20 2:00 1:00 S
Rule Palestine 2042 only - Sep 27 2:00 1:00 S
Rule Palestine 2043 only - Aug 1 2:00 0 -
Rule Palestine 2043 only - Sep 12 2:00 1:00 S
Rule Palestine 2043 only - Sep 19 2:00 1:00 S
Rule Palestine 2044 only - Jul 23 2:00 0 -
Rule Palestine 2044 only - Aug 27 2:00 1:00 S
Rule Palestine 2044 only - Sep 3 2:00 1:00 S
Rule Palestine 2045 only - Jul 15 2:00 0 -
Rule Palestine 2045 only - Aug 19 2:00 1:00 S
Rule Palestine 2045 only - Aug 26 2:00 1:00 S
Rule Palestine 2046 only - Jun 30 2:00 0 -
Rule Palestine 2046 only - Aug 11 2:00 1:00 S
Rule Palestine 2046 only - Aug 18 2:00 1:00 S
Rule Palestine 2047 only - Jun 22 2:00 0 -
Rule Palestine 2047 only - Jul 27 2:00 1:00 S
Rule Palestine 2047 only - Aug 3 2:00 1:00 S
Rule Palestine 2048 only - Jun 6 2:00 0 -
Rule Palestine 2048 only - Jul 18 2:00 1:00 S
Rule Palestine 2048 only - Jul 25 2:00 1:00 S
Rule Palestine 2049 only - May 29 2:00 0 -
Rule Palestine 2049 only - Jul 3 2:00 1:00 S
Rule Palestine 2049 only - Jul 10 2:00 1:00 S
Rule Palestine 2050 only - May 21 2:00 0 -
Rule Palestine 2050 only - Jun 25 2:00 1:00 S
Rule Palestine 2050 only - Jul 2 2:00 1:00 S
Rule Palestine 2051 only - May 6 2:00 0 -
Rule Palestine 2051 only - Jun 17 2:00 1:00 S
Rule Palestine 2051 only - Jun 24 2:00 1:00 S
Rule Palestine 2052 only - Apr 27 2:00 0 -
Rule Palestine 2052 only - Jun 1 2:00 1:00 S
Rule Palestine 2052 only - Jun 8 2:00 1:00 S
Rule Palestine 2053 only - Apr 12 2:00 0 -
Rule Palestine 2053 only - May 24 2:00 1:00 S
Rule Palestine 2053 only - May 31 2:00 1:00 S
Rule Palestine 2054 only - Apr 4 2:00 0 -
Rule Palestine 2054 only - May 16 2:00 1:00 S
Rule Palestine 2055 only - May 1 2:00 1:00 S
Rule Palestine 2056 only - Apr 22 2:00 1:00 S
Rule Palestine 2057 only - Apr 7 2:00 1:00 S
Rule Palestine 2058 max - Mar Sat<=30 2:00 1:00 S
Rule Palestine 2054 only - May 23 2:00 1:00 S
Rule Palestine 2055 only - May 8 2:00 1:00 S
Rule Palestine 2056 only - Apr 29 2:00 1:00 S
Rule Palestine 2057 only - Apr 14 2:00 1:00 S
Rule Palestine 2058 only - Apr 6 2:00 1:00 S
Rule Palestine 2059 max - Mar Sat<=30 2:00 1:00 S
Rule Palestine 2068 only - Oct 20 2:00 0 -
Rule Palestine 2069 only - Oct 12 2:00 0 -
Rule Palestine 2070 only - Oct 4 2:00 0 -
Rule Palestine 2071 only - Sep 19 2:00 0 -
Rule Palestine 2072 only - Sep 10 2:00 0 -
Rule Palestine 2072 only - Oct 15 2:00 1:00 S
Rule Palestine 2072 only - Oct 22 2:00 1:00 S
Rule Palestine 2072 max - Oct Sat<=30 2:00 0 -
Rule Palestine 2073 only - Sep 2 2:00 0 -
Rule Palestine 2073 only - Oct 7 2:00 1:00 S
Rule Palestine 2073 only - Oct 14 2:00 1:00 S
Rule Palestine 2074 only - Aug 18 2:00 0 -
Rule Palestine 2074 only - Sep 29 2:00 1:00 S
Rule Palestine 2074 only - Oct 6 2:00 1:00 S
Rule Palestine 2075 only - Aug 10 2:00 0 -
Rule Palestine 2075 only - Sep 14 2:00 1:00 S
Rule Palestine 2075 only - Sep 21 2:00 1:00 S
Rule Palestine 2076 only - Jul 25 2:00 0 -
Rule Palestine 2076 only - Sep 5 2:00 1:00 S
Rule Palestine 2076 only - Sep 12 2:00 1:00 S
Rule Palestine 2077 only - Jul 17 2:00 0 -
Rule Palestine 2077 only - Aug 28 2:00 1:00 S
Rule Palestine 2077 only - Sep 4 2:00 1:00 S
Rule Palestine 2078 only - Jul 9 2:00 0 -
Rule Palestine 2078 only - Aug 13 2:00 1:00 S
Rule Palestine 2078 only - Aug 20 2:00 1:00 S
Rule Palestine 2079 only - Jun 24 2:00 0 -
Rule Palestine 2079 only - Aug 5 2:00 1:00 S
Rule Palestine 2079 only - Aug 12 2:00 1:00 S
Rule Palestine 2080 only - Jun 15 2:00 0 -
Rule Palestine 2080 only - Jul 20 2:00 1:00 S
Rule Palestine 2080 only - Jul 27 2:00 1:00 S
Rule Palestine 2081 only - Jun 7 2:00 0 -
Rule Palestine 2081 only - Jul 12 2:00 1:00 S
Rule Palestine 2081 only - Jul 19 2:00 1:00 S
Rule Palestine 2082 only - May 23 2:00 0 -
Rule Palestine 2082 only - Jul 4 2:00 1:00 S
Rule Palestine 2082 only - Jul 11 2:00 1:00 S
Rule Palestine 2083 only - May 15 2:00 0 -
Rule Palestine 2083 only - Jun 19 2:00 1:00 S
Rule Palestine 2083 only - Jun 26 2:00 1:00 S
Rule Palestine 2084 only - Apr 29 2:00 0 -
Rule Palestine 2084 only - Jun 10 2:00 1:00 S
Rule Palestine 2084 only - Jun 17 2:00 1:00 S
Rule Palestine 2085 only - Apr 21 2:00 0 -
Rule Palestine 2085 only - Jun 2 2:00 1:00 S
Rule Palestine 2085 only - Jun 9 2:00 1:00 S
Rule Palestine 2086 only - Apr 13 2:00 0 -
Rule Palestine 2086 only - May 18 2:00 1:00 S
Rule Palestine 2086 only - May 25 2:00 1:00 S

# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
@@ -3606,15 +3628,15 @@ Zone Asia/Hebron 2:20:23 - LMT 1900 Oct

# Philippines

# From Paul Eggert (2018-11-18):
# From Paul Eggert (2024-01-21):
# The Spanish initially used American (west-of-Greenwich) time.
# It is unknown what time Manila kept when the British occupied it from
# 1762-10-06 through 1764-04; for now assume it kept American time.
# On 1844-08-16, Narciso Clavería, governor-general of the
# Philippines, issued a proclamation announcing that 1844-12-30 was to
# be immediately followed by 1845-01-01; see R.H. van Gent's
# History of the International Date Line
# https://www.staff.science.uu.nl/~gent0113/idl/idl_philippines.htm
# https://webspace.science.uu.nl/~gent0113/idl/idl_philippines.htm
# The rest of the data entries are from Shanks & Pottenger.

# From Jesper Nørgaard Welen (2006-04-26):
@@ -4041,7 +4063,8 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
# The English-language name of Vietnam's most populous city is "Ho Chi Minh
# City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters.

# From Paul Eggert (2022-07-27) after a 2014 heads-up from Trần Ngọc Quân:
# From Paul Eggert (2024-01-14) after a 2014 heads-up from Trần Ngọc Quân
# and a 2024-01-14 heads-up from Đoàn Trần Công Danh:
# Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)"
# (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50,
# is quoted verbatim in:
@@ -4071,24 +4094,45 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
#
# Trần cites the following sources; it's unclear which supplied the info above.
#
# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội,
# No. 9, Paris, February 1982.
# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội,
# No. 9, Paris, February 1982.
#
# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)",
# NXB Thống kê, Hanoi, 2000.
#
# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)",
# NXB Thống kê, Hanoi, 2000.
# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
# NXB Thuận Hoá, Huế, 1995.
#
# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
# NXB Thuận Hoá, Huế, 1995.
# Here is the decision for the September 1945 transition:
# Võ Nguyên Giáp, Việt Nam Dân Quốc Công Báo, No. 1 (1945-09-29), page 13
# http://baochi.nlv.gov.vn/baochi/cgi-bin/baochi?a=d&d=JwvzO19450929.2.5&dliv=none
# It says that on 1945-09-01 at 24:00, Vietnam moved back two hours, to +07.
# It also mentions a 1945-03-29 decree (by a Japanese Goveror-General)
# to set the time zone to +09, but does not say whether that decree
# merely legalized an earlier change to +09.
#
# July 1955 transition:
# Ngô Đình Diệm, Công Báo Việt Nam, No. 92 (1955-07-02), page 1780-1781
# Ordinance (Dụ) No. 46 (1955-06-25)
# http://ddsnext.crl.edu/titles/32341#?c=0&m=29&s=0&cv=4&r=0&xywh=-89%2C342%2C1724%2C1216
# It says that on 1955-07-01 at 01:00, South Vietnam moved back 1 hour (to +07).
#
# December 1959 transition:
# Ngô Đình Diệm, Công Báo Việt Nam Cộng Hòa, 1960 part 1 (1960-01-02), page 62
# Decree (Sắc lệnh) No. 362-TTP (1959-12-30)
# http://ddsnext.crl.edu/titles/32341#?c=0&m=138&s=0&cv=793&r=0&xywh=-54%2C1504%2C1705%2C1202
# It says that on 1959-12-31 at 23:00, South Vietnam moved forward 1 hour (to +08).


# Zone NAME STDOFF RULES FORMAT [UNTIL]
#STDOFF 7:06:30.13
Zone Asia/Ho_Chi_Minh 7:06:30 - LMT 1906 Jul 1
7:06:30 - PLMT 1911 May 1 # Phù Liễn MT
7:00 - +07 1942 Dec 31 23:00
8:00 - +08 1945 Mar 14 23:00
9:00 - +09 1945 Sep 2
9:00 - +09 1945 Sep 1 24:00
7:00 - +07 1947 Apr 1
8:00 - +08 1955 Jul 1
8:00 - +08 1955 Jul 1 01:00
7:00 - +07 1959 Dec 31 23:00
8:00 - +08 1975 Jun 13
7:00 - +07
14 changes: 9 additions & 5 deletions australasia
Original file line number Diff line number Diff line change
@@ -420,11 +420,11 @@ Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva

# French Polynesia
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct # Rikitea
Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct 1 # Rikitea
-9:00 - -09
Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct
Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct 1
-9:30 - -0930
Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct # Papeete
Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct 1 # Papeete
-10:00 - -10
# Clipperton (near North America) is administered from French Polynesia;
# it is uninhabited.
@@ -802,7 +802,7 @@ Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5
# Solomon Is
# excludes Bougainville, for which see Papua New Guinea
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara
Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct 1 # Honiara
11:00 - +11

# Tokelau
@@ -963,6 +963,10 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila
# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
# https://www.jstor.org/stable/1774359
#
# For the 1911/1912 establishment of standard time in French possessions, see:
# Société Française de Physique, Recueil de constantes physiques (1913),
# page 752, 18b.
#
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
@@ -2039,7 +2043,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila
# ordaining - by a masterpiece of diplomatic flattery - that
# the Fourth of July should be celebrated twice in that year."
# This happened in 1892, according to the Evening News (Sydney) of 1892-07-20.
# https://www.staff.science.uu.nl/~gent0113/idl/idl.htm
# https://webspace.science.uu.nl/~gent0113/idl/idl_alaska_samoa.htm

# Although Shanks & Pottenger says they both switched to UT -11:30
# in 1911, and to -11 in 1950. many earlier sources give -11
2 changes: 1 addition & 1 deletion checknow.awk
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ END {
for (zone in zone_data) {
data = zone_data[zone]
if (!zonenow[data]) {
printf "checknow.tab should have one of:%s\n", zones[data]
printf "zonenow.tab should have one of:%s\n", zones[data]
zonenow[data] = zone # This suppresses duplicate diagnostics.
status = 1
}
2 changes: 1 addition & 1 deletion etcetera
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

# These entries are for uses not otherwise covered by the tz database.
# Their main practical use is for platforms like Android that lack
# support for POSIX-style TZ strings. On such platforms these entries
# support for POSIX.1-2017-style TZ strings. On such platforms these entries
# can be useful if the timezone database is wrong or if a ship or
# aircraft at sea is not in a timezone.

29 changes: 27 additions & 2 deletions europe
Original file line number Diff line number Diff line change
@@ -990,9 +990,34 @@ Zone Europe/Sofia 1:33:16 - LMT 1880
# Czech Republic (Czechia)
# Slovakia
#
# From Paul Eggert (2018-04-15):
# The source for Czech data is: Kdy začíná a končí letní čas. 2018-04-15.
# From Ivan Benovic (2024-01-30):
# https://www.slov-lex.sk/pravne-predpisy/SK/ZZ/1946/54/
# (This is an official link to the Czechoslovak Summer Time Act of
# March 8, 1946 that authorizes the Czechoslovak government to set the
# exact dates of change to summer time and back to Central European Time.
# The act also implicitly confirms Central European Time as the
# official time zone of Czechoslovakia and currently remains in force
# in both the Czech Republic and Slovakia.)
# https://www.psp.cz/eknih/1945pns/tisky/t0216_00.htm
# (This is a link to the original legislative proposal dating back to
# February 22, 1946. The accompanying memorandum to the proposal says
# that an advisory committee on European railroad transportation that
# met in Brussels in October 1945 decided that the change of time
# should be carried out in all participating countries in a strictly
# coordinated manner....)
#
# From Paul Eggert (2024-01-30):
# The source for Czech data is: Kdy začíná a končí letní čas.
# https://kalendar.beda.cz/kdy-zacina-a-konci-letni-cas
# Its main text disagrees with its quoted sources only in 1918,
# where the main text says spring and autumn transitions
# occurred at 02:00 and 03:00 respectively (as usual),
# whereas the 1918 source "Oznámení o zavedení letního času v roce 1918"
# says transitions were at 01:00 and 02:00 respectively.
# As the 1918 source appears to be a humorous piece, and it is
# unlikely that Prague would have disagreed with its neighbors by an hour,
# go with the main text for now.
#
# We know of no English-language name for historical Czech winter time;
# abbreviate it as "GMT", as it happened to be GMT.
#
373 changes: 119 additions & 254 deletions leap-seconds.list

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions leapseconds.awk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generate zic format 'leapseconds' from NIST format 'leap-seconds.list'.
# Generate zic format 'leapseconds' from NIST/IERS format 'leap-seconds.list'.

# This file is in the public domain.

@@ -21,13 +21,10 @@ BEGIN {
print "# This file is in the public domain."
print ""
print "# This file is generated automatically from the data in the public-domain"
print "# NIST format leap-seconds.list file, which can be copied from"
print "# <ftp://ftp.nist.gov/pub/time/leap-seconds.list>"
print "# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>."
print "# The NIST file is used instead of its IERS upstream counterpart"
print "# NIST/IERS format leap-seconds.list file, which can be copied from"
print "# <https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list>"
print "# because under US law the NIST file is public domain"
print "# whereas the IERS file's copyright and license status is unclear."
print "# or, in a variant with different comments, from"
print "# <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>."
print "# For more about leap-seconds.list, please see"
print "# The NTP Timescale and Leap Seconds"
print "# <https://www.eecis.udel.edu/~mills/leap.html>."
31 changes: 18 additions & 13 deletions localtime.c
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

/*
** Leap second handling from Bradley White.
** POSIX-style TZ environment variable handling from Guy Harris.
** POSIX.1-1988 style TZ environment variable handling from Guy Harris.
*/

/*LINTLIBRARY*/
@@ -106,7 +106,7 @@ static char const UNSPEC[] = "-00";
for ttunspecified to work without crashing. */
enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };

/* Limit to time zone abbreviation length in POSIX-style TZ strings.
/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings.
This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
#ifndef TZNAME_MAXIMUM
# define TZNAME_MAXIMUM 255
@@ -935,7 +935,8 @@ getoffset(register const char *strp, int_fast32_t *const offsetp)

/*
** Given a pointer into a timezone string, extract a rule in the form
** date[/time]. See POSIX section 8 for the format of "date" and "time".
** date[/time]. See POSIX Base Definitions section 8.3 variable TZ
** for the format of "date" and "time".
** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule.
*/
@@ -1079,7 +1080,7 @@ transtime(const int year, register const struct rule *const rulep,
}

/*
** Given a POSIX section 8-style TZ string, fill in the rule tables as
** Given a POSIX.1-2017-style TZ string, fill in the rule tables as
** appropriate.
*/

@@ -1204,7 +1205,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
}

yearlim = yearbeg;
if (increment_overflow(&yearlim, YEARSPERREPEAT + 1))
if (increment_overflow(&yearlim, years_of_observations))
yearlim = INT_MAX;
for (year = yearbeg; year < yearlim; year++) {
int_fast32_t
@@ -1241,7 +1242,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
if (endtime < leaplo) {
yearlim = year;
if (increment_overflow(&yearlim,
YEARSPERREPEAT + 1))
years_of_observations))
yearlim = INT_MAX;
}
if (increment_overflow_time
@@ -1253,7 +1254,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
if (! timecnt) {
sp->ttis[0] = sp->ttis[1];
sp->typecnt = 1; /* Perpetual DST. */
} else if (YEARSPERREPEAT < year - yearbeg)
} else if (years_of_observations <= year - yearbeg)
sp->goback = sp->goahead = true;
} else {
register int_fast32_t theirstdoffset;
@@ -1312,8 +1313,8 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
/*
** Transitions from DST to DDST
** will effectively disappear since
** POSIX provides for only one DST
** offset.
** POSIX.1-2017 provides for only one
** DST offset.
*/
if (isdst && !sp->ttis[j].tt_ttisstd) {
sp->ats[i] += dstoffset -
@@ -1483,7 +1484,8 @@ tzfree(timezone_t sp)
**
** If successful and SETNAME is nonzero,
** set the applicable parts of tzname, timezone and altzone;
** however, it's OK to omit this step if the timezone is POSIX-compatible,
** however, it's OK to omit this step
** if the timezone is compatible with POSIX.1-2017
** since in that case tzset should have already done this step correctly.
** SETNAME's type is int_fast32_t for compatibility with gmtsub,
** but it is actually a boolean and its value should be 0 or 1.
@@ -2292,15 +2294,18 @@ timelocal(struct tm *tmp)
tmp->tm_isdst = -1; /* in case it wasn't initialized */
return mktime(tmp);
}
#else
#endif

#ifndef EXTERN_TIMEOFF
# ifndef timeoff
# define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */
# endif
static
# define EXTERN_TIMEOFF static
#endif

/* This function is obsolescent and may disapper in future releases.
Callers can instead use mktime_z with a fixed-offset zone. */
time_t
EXTERN_TIMEOFF time_t
timeoff(struct tm *tmp, long offset)
{
if (tmp)
152 changes: 150 additions & 2 deletions newstrftime.3
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ strftime \- format date and time
The
.B strftime
function formats the information from
.I timeptr
.BI * timeptr
into the array pointed to by
.I buf
according to the string pointed to by
@@ -85,47 +85,94 @@ bytes are placed into the array.
.PP
Each conversion specification is replaced by the characters as
follows which are then copied into the array.
The characters depend on the values of zero or more members of
.BI * timeptr
as specified by brackets in the description.
If a bracketed member name is followed by
.q + ,
.B strftime
can use the named member even though POSIX.1-2017 does not list it;
if the name is followed by
.q \*- ,
.B strftime
ignores the member even though POSIX.1-2017 lists it
which means portable code should set it.
For portability,
.BI * timeptr
should be initialized as if by a successful call to
.BR gmtime ,
.BR localtime ,
.BR mktime ,
.BR timegm ,
or similar functions.
.TP
%A
is replaced by the locale's full weekday name.
.RI [ tm_wday ]
.TP
%a
is replaced by the locale's abbreviated weekday name.
.RI [ tm_wday ]
.TP
%B
is replaced by the locale's full month name.
.RI [ tm_mon ]
.TP
%b or %h
is replaced by the locale's abbreviated month name.
.RI [ tm_mon ]
.TP
%C
is replaced by the century (a year divided by 100 and truncated to an integer)
as a decimal number [00,99].
as a decimal number, with at least two digits by default.
.RI [ tm_year ]
.TP
%c
is replaced by the locale's appropriate date and time representation.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_isdst \*-].
.TP
%D
is equivalent to
.c %m/%d/%y .
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ]
.TP
%d
is replaced by the day of the month as a decimal number [01,31].
.RI [ tm_mday ]
.TP
%e
is replaced by the day of month as a decimal number [1,31];
single digits are preceded by a blank.
.RI [ tm_mday ]
.TP
%F
is equivalent to
.c %Y-%m-%d
(the ISO 8601 date format).
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ]
.TP
%G
is replaced by the ISO 8601 year with century as a decimal number.
See also the
.c %V
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%g
is replaced by the ISO 8601 year without century as a decimal number [00,99].
@@ -134,29 +181,39 @@ This is the year that includes the greater part of the week.
See also the
.c %V
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%H
is replaced by the hour (24-hour clock) as a decimal number [00,23].
.RI [ tm_hour ]
.TP
%I
is replaced by the hour (12-hour clock) as a decimal number [01,12].
.RI [ tm_hour ]
.TP
%j
is replaced by the day of the year as a decimal number [001,366].
.RI [ tm_yday ]
.TP
%k
is replaced by the hour (24-hour clock) as a decimal number [0,23];
single digits are preceded by a blank.
.RI [ tm_hour ]
.TP
%l
is replaced by the hour (12-hour clock) as a decimal number [1,12];
single digits are preceded by a blank.
.RI [ tm_hour ]
.TP
%M
is replaced by the minute as a decimal number [00,59].
.RI [ tm_min ]
.TP
%m
is replaced by the month as a decimal number [01,12].
.RI [ tm_mon ]
.TP
%n
is replaced by a newline.
@@ -166,39 +223,73 @@ is replaced by the locale's equivalent of either
.q AM
or
.q PM .
.RI [ tm_hour ]
.TP
%R
is replaced by the time in the format
.c %H:%M .
.RI [ tm_hour ,
.IR tm_min ]
.TP
%r
is replaced by the locale's representation of 12-hour clock time
using AM/PM notation.
.RI [ tm_hour ,
.IR tm_min ,
.IR tm_sec ]
.TP
%S
is replaced by the second as a decimal number [00,60].
The range of
seconds is [00,60] instead of [00,59] to allow for the periodic occurrence
of leap seconds.
.RI [ tm_sec ]
.TP
%s
is replaced by the number of seconds since the Epoch (see
.BR ctime (3)).
Although %s is reliable in this implementation,
it can have glitches on other platforms (notably platforms lacking
.IR tm_gmtoff ),
so portable code should format a
.B time_t
value directly via something like
.B sprintf
instead of via
.B localtime
followed by
.B strftime
with "%s".
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_isdst \*-].
.TP
%T
is replaced by the time in the format
.c %H:%M:%S .
.RI [ tm_hour ,
.IR tm_min ,
.IR tm_sec ]
.TP
%t
is replaced by a tab.
.TP
%U
is replaced by the week number of the year (Sunday as the first day of
the week) as a decimal number [00,53].
.RI [ tm_wday ,
.IR tm_yday ,
.IR tm_year \*-]
.TP
%u
is replaced by the weekday (Monday as the first day of the week)
as a decimal number [1,7].
.RI [ tm_wday ]
.TP
%V
is replaced by the week number of the year (Monday as the first day of
@@ -208,30 +299,64 @@ it is week 53 of the previous year, and the next week is week 1.
The year is given by the
.c %G
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%W
is replaced by the week number of the year (Monday as the first day of
the week) as a decimal number [00,53].
.RI [ tm_yday ,
.IR tm_wday ]
.TP
%w
is replaced by the weekday (Sunday as the first day of the week)
as a decimal number [0,6].
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%X
is replaced by the locale's appropriate time representation.
.RI [ tm_year \*-,
.IR tm_yday \*-,
.IR tm_mon \*-,
.IR tm_mday \*-,
.IR tm_wday \*-,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_isdst \*-].
.TP
%x
is replaced by the locale's appropriate date representation.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour \*-,
.IR tm_min \*-,
.IR tm_sec \*-,
.IR tm_gmtoff \*-,
.IR tm_zone \*-,
.IR tm_isdst \*-].
.TP
%Y
is replaced by the year with century as a decimal number.
.RI [ tm_year ]
.TP
%y
is replaced by the year without century as a decimal number [00,99].
.RI [ tm_year ]
.TP
%Z
is replaced by the time zone abbreviation,
or by the empty string if this is not determinable.
.RI [ tm_zone +,
.IR tm_isdst \*-]
.TP
%z
is replaced by the offset from the Prime Meridian
@@ -244,6 +369,9 @@ but local time is indeterminate; by convention this is used for
locations while uninhabited, and corresponds to a zero offset when the
time zone abbreviation begins with
.q "\*-" .
.RI [ tm_gmtoff +,
.IR tm_zone +,
.IR tm_isdst \*-]
.TP
%%
is replaced by a single %.
@@ -252,6 +380,26 @@ is replaced by a single %.
is replaced by the locale's date and time in
.BR date (1)
format.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff ,
.IR tm_zone ]
.PP
As a side effect,
.B strftime
also behaves as if
.B tzset
were called.
This is for compatibility with older platforms, as required by POSIX;
it is not needed for
.BR tzset 's
own use.
.SH "RETURN VALUE"
If the conversion is successful,
.B strftime
164 changes: 99 additions & 65 deletions newtzset.3
Original file line number Diff line number Diff line change
@@ -9,9 +9,9 @@ tzset \- initialize time conversion information
.el .ds - \-
.B #include <time.h>
.PP
.B timezone_t tzalloc(char const *TZ);
.BI "timezone_t tzalloc(char const *" TZ );
.PP
.B void tzfree(timezone_t tz);
.BI "void tzfree(timezone_t " tz );
.PP
.B void tzset(void);
.PP
@@ -31,62 +31,30 @@ The
.B tzalloc
function
allocates and returns a timezone object described by
.BR TZ .
If
.B TZ
is not a valid timezone description, or if the object cannot be allocated,
.B tzalloc
returns a null pointer and sets
.BR errno .
.PP
The
.B tzfree
function
frees a timezone object
.BR tz ,
which should have been successfully allocated by
.BR tzalloc .
This invalidates any
.B tm_zone
pointers that
.B tz
was used to set.
.PP
The
.B tzset
function
acts like
.BR tzalloc(getenv("TZ")) ,
except it saves any resulting timezone object into internal
storage that is accessed by
.BR localtime ,
.BR localtime_r ,
and
.BR mktime .
The anonymous shared timezone object is freed by the next call to
.BR tzset .
If the implied call to
.B tzalloc
fails,
.B tzset
falls back on Universal Time (UT).
.IR TZ .
.PP
If
.B TZ
is null, the best available approximation to local (wall
.I TZ
is a null pointer,
.B tzalloc
uses the best available approximation to local (wall
clock) time, as specified by the
.BR tzfile (5)-format
file
.B localtime
in the system time conversion information directory, is used.
in the system time conversion information directory.
.PP
If
.B TZ
.I TZ
is the empty string,
UT is used, with the abbreviation "UTC"
.B tzalloc
uses Universal Time (UT), with the abbreviation "UTC"
and without leap second correction; please see
.BR newctime (3)
for more about UT, UTC, and leap seconds. If
.B TZ
for more about UT, UTC, and leap seconds.
.PP
If
.I TZ
is nonnull and nonempty:
.IP
if the value begins with a colon, it is used as a pathname of a file
@@ -98,18 +66,19 @@ and, if that file cannot be read, is used directly as a specification of
the time conversion information.
.PP
When
.B TZ
is used as a pathname, if it begins with a slash,
it is used as an absolute pathname; otherwise,
it is used as a pathname relative to a system time conversion information
.I TZ
contents are used as a pathname, a pathname beginning with
.q "/"
is used as-is; otherwise
the pathname is relative to a system time conversion information
directory.
The file must be in the format specified in
.BR tzfile (5).
.PP
When
.B TZ
.I TZ
is used directly as a specification of the time conversion information,
it must have the following syntax (spaces inserted for clarity):
it must have the following syntax:
.IP
\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]]
.PP
@@ -196,7 +165,7 @@ describes when the change back happens. Each
.I time
field describes when, in current local time, the change to the other
time is made.
As an extension to POSIX, daylight saving is assumed to be in effect
As an extension to POSIX.1-2017, daylight saving is assumed to be in effect
all year if it begins January 1 at 00:00 and ends December 31 at
24:00 plus the difference between daylight saving and standard time,
leaving no room for standard time in the calendar.
@@ -243,11 +212,11 @@ The
.I time
has the same format as
.I offset
except that POSIX does not allow a leading sign (\c
except that POSIX.1-2017 does not allow a leading sign (\c
.q "\*-"
or
.q "+" ).
As an extension to POSIX, the hours part of
As an extension to POSIX.1-2017, the hours part of
.I time
can range from \-167 through 167; this allows for unusual rules such
as
@@ -259,9 +228,9 @@ is not given, is
.RE
.LP
Here are some examples of
.B TZ
.I TZ
values that directly specify the timezone; they use some of the
extensions to POSIX.
extensions to POSIX.1-2017.
.TP
.B EST5
stands for US Eastern Standard
@@ -307,7 +276,7 @@ and
.q "\*-02".
.PP
If
.B TZ
.I TZ
specifies daylight saving time but does not specify a
.IR rule ,
and the optional
@@ -323,20 +292,85 @@ standard and daylight saving time offsets from UT
replaced by those specified by the
.I offset
values in
.BR TZ .
.IR TZ .
However, the
.B posixrules
file is obsolete: if it is present it is only for backward compatibility,
and it does not work reliably.
Therefore, applications that specify a
.B TZ
string with daylight saving time should specify rules explicitly.
Therefore, if a
.I TZ
string directly specifies a timezone with daylight saving time,
it should specify the daylight saving rules explicitly.
.PP
For compatibility with System V Release 3.1, a semicolon
.RB ( ; )
may be used to separate the
.I rule
from the rest of the specification.
from the rest of the specification;
this is an extension to POSIX.
.PP
The
.B tzfree
function
frees a timezone object
.IR tz ,
which should have been successfully allocated by
.BR tzalloc .
This invalidates any
.B tm_zone
pointers that
.I tz
was used to set.
.PP
The
.B tzset
function
acts like
.BR tzalloc(getenv("TZ")) ,
except it saves any resulting timezone object into internal
storage that is accessed by
.BR localtime ,
.BR localtime_r ,
and
.BR mktime .
The anonymous shared timezone object is freed by the next call to
.BR tzset .
If the implied call to
.B getenv
fails,
.B tzset
acts like
.BR tzalloc(nullptr) ;
if the implied call to
.B tzalloc
fails,
.B tzset
falls back on UT.
.SH "RETURN VALUE"
If successful, the
.B tzalloc
function returns a nonnull pointer to the newly allocated object.
Otherwise, it returns a null pointer and sets
.IR errno .
.SH ERRORS
.TP
.B EOVERFLOW
.I TZ
directly specifies time conversion information,
and contains an integer out of machine range
or a time zone abbreviation that is too long for this platform.
.PP
The
.B tzalloc
function may also fail and set
.I errno
for any of the errors specified for the routines
.BR access (2),
.BR close (2),
.BR malloc (3),
.BR open (2),
and
.BR read (2).
.SH FILES
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
/etc/localtime local timezone file
29 changes: 19 additions & 10 deletions northamerica
Original file line number Diff line number Diff line change
@@ -1268,6 +1268,10 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
# <http://cs.ucla.edu/~eggert/The-Waste-of-Daylight-19th.pdf>
# [PDF] (1914-03)
#
# For the 1911/1912 establishment of standard time in French possessions, see:
# Société Française de Physique, Recueil de constantes physiques (1913),
# page 752, 18b.
#
# See the 'europe' file for Greenland.

# Canada
@@ -1354,7 +1358,7 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
# From Paul Eggert (2014-10-18):
# H. David Matthews and Mary Vincent's map
# "It's about TIME", _Canadian Geographic_ (September-October 1998)
# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp
# https://web.archive.org/web/19990827055050/https://canadiangeographic.ca/SO98/geomap.htm
# contains detailed boundaries for regions observing nonstandard
# time and daylight saving time arrangements in Canada circa 1998.
#
@@ -1642,6 +1646,15 @@ Zone America/Moncton -4:19:08 - LMT 1883 Dec 9
# Some cities in the United States have pushed the deadline back
# three weeks and will change over from daylight saving in October.

# From Chris Walton (2024-01-09):
# The [Toronto] changes in 1947, 1948, and 1949 took place at 2:00 a.m. local
# time instead of midnight.... Toronto Daily Star - ...
# April 2, 1947 - Page 39 ... April 7, 1948 - Page 13 ...
# April 2, 1949 - Page 1 ... April 7, 1949 - Page 24 ...
# November 25, 1949 - Page 52 ... April 21, 1950 - Page 14 ...
# September 19, 1950 - Page 46 ... September 20, 1950 - Page 3 ...
# November 24, 1950 - Page 21

# From Arthur David Olson (2010-07-17):
#
# "Standard Time and Time Zones in Canada" appeared in
@@ -1703,13 +1716,9 @@ Rule Toronto 1927 1937 - Sep Sun>=25 2:00 0 S
Rule Toronto 1928 1937 - Apr Sun>=25 2:00 1:00 D
Rule Toronto 1938 1940 - Apr lastSun 2:00 1:00 D
Rule Toronto 1938 1939 - Sep lastSun 2:00 0 S
Rule Toronto 1945 1946 - Sep lastSun 2:00 0 S
Rule Toronto 1946 only - Apr lastSun 2:00 1:00 D
Rule Toronto 1947 1949 - Apr lastSun 0:00 1:00 D
Rule Toronto 1947 1948 - Sep lastSun 0:00 0 S
Rule Toronto 1949 only - Nov lastSun 0:00 0 S
Rule Toronto 1950 1973 - Apr lastSun 2:00 1:00 D
Rule Toronto 1950 only - Nov lastSun 2:00 0 S
Rule Toronto 1945 1948 - Sep lastSun 2:00 0 S
Rule Toronto 1946 1973 - Apr lastSun 2:00 1:00 D
Rule Toronto 1949 1950 - Nov lastSun 2:00 0 S
Rule Toronto 1951 1956 - Sep lastSun 2:00 0 S
# Shanks & Pottenger say Toronto ended DST a week early in 1971,
# namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
@@ -3432,7 +3441,7 @@ Zone America/Jamaica -5:07:10 - LMT 1890 # Kingston
# Martinique
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France
-4:04:20 - FFMT 1911 May # Fort-de-France MT
-4:04:20 - FFMT 1911 May 1 # Fort-de-France MT
-4:00 - AST 1980 Apr 6
-4:00 1:00 ADT 1980 Sep 28
-4:00 - AST
@@ -3539,7 +3548,7 @@ Zone America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12:00 # San Juan
# St Pierre and Miquelon
# There are too many St Pierres elsewhere, so we'll use 'Miquelon'.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre
Zone America/Miquelon -3:44:40 - LMT 1911 Jun 15 # St Pierre
-4:00 - AST 1980 May
-3:00 - -03 1987
-3:00 Canada -03/-02
30 changes: 28 additions & 2 deletions private.h
Original file line number Diff line number Diff line change
@@ -756,7 +756,7 @@ struct tm *offtime(time_t const *, long);
time_t timelocal(struct tm *);
# endif
# if TZ_TIME_T || !defined timeoff
time_t timeoff(struct tm *, long);
# define EXTERN_TIMEOFF
# endif
# if TZ_TIME_T || !defined time2posix
time_t time2posix(time_t);
@@ -768,7 +768,8 @@ time_t posix2time(time_t);

/* Infer TM_ZONE on systems where this information is known, but suppress
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
#if (defined __GLIBC__ \
#if (200809 < _POSIX_VERSION \
|| defined __GLIBC__ \
|| defined __tm_zone /* musl */ \
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__))
@@ -898,6 +899,19 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
# define UNINIT_TRAP 0
#endif

/* localtime.c sometimes needs access to timeoff if it is not already public.
tz_private_timeoff should be used only by localtime.c. */
#if (!defined EXTERN_TIMEOFF \
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
# ifndef timeoff
# define timeoff tz_private_timeoff
# endif
# define EXTERN_TIMEOFF
#endif
#ifdef EXTERN_TIMEOFF
time_t timeoff(struct tm *, long);
#endif

#ifdef DEBUG
# undef unreachable
# define unreachable() abort()
@@ -957,6 +971,18 @@ enum {
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)

/* How many years to generate (in zic.c) or search through (in localtime.c).
This is two years larger than the obvious 400, to avoid edge cases.
E.g., suppose a non-POSIX.1-2017 rule applies from 2012 on with transitions
in March and September, plus one-off transitions in November 2013.
If zic looked only at the last 400 years, it would set max_year=2413,
with the intent that the 400 years 2014 through 2413 will be repeated.
The last transition listed in the tzfile would be in 2413-09,
less than 400 years after the last one-off transition in 2013-11.
Two years is not overkill for localtime.c, as a one-year bump
would mishandle 2023d's America/Ciudad_Juarez for November 2422. */
enum { years_of_observations = YEARSPERREPEAT + 2 };

enum {
TM_SUNDAY,
TM_MONDAY,
5 changes: 4 additions & 1 deletion southamerica
Original file line number Diff line number Diff line change
@@ -1570,8 +1570,11 @@ Zone Atlantic/Stanley -3:51:24 - LMT 1890
-3:00 - -03

# French Guiana
# For the 1911/1912 establishment of standard time in French possessions, see:
# Société Française de Physique, Recueil de constantes physiques (1913),
# page 752, 18b.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Cayenne -3:29:20 - LMT 1911 Jul
Zone America/Cayenne -3:29:20 - LMT 1911 Jul 1
-4:00 - -04 1967 Oct
-3:00 - -03

7 changes: 4 additions & 3 deletions strftime.c
Original file line number Diff line number Diff line change
@@ -327,11 +327,12 @@ _fmt(const char *format, const struct tm *t, char *pt,
tm.tm_mday = t->tm_mday;
tm.tm_mon = t->tm_mon;
tm.tm_year = t->tm_year;
#ifdef TM_GMTOFF
mkt = timeoff(&tm, t->TM_GMTOFF);
#else
tm.tm_isdst = t->tm_isdst;
#if defined TM_GMTOFF && ! UNINIT_TRAP
tm.TM_GMTOFF = t->TM_GMTOFF;
#endif
mkt = mktime(&tm);
#endif
/* If mktime fails, %s expands to the
value of (time_t) -1 as a failure
marker; this is better in practice
37 changes: 21 additions & 16 deletions theory.html
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ <h2 id="scope">Scope of the <code><abbr>tz</abbr></code> database</h2>
Edition.
Because the database's scope encompasses real-world changes to civil
timekeeping, its model for describing time is more complex than the
standard and daylight saving times supported by POSIX.
standard and daylight saving times supported by POSIX.1-2017.
A <code><abbr>tz</abbr></code> timezone corresponds to a ruleset that can
have more than two changes per year, these changes need not merely
flip back and forth between two alternatives, and the rules themselves
@@ -187,7 +187,7 @@ <h2 id="naming">Timezone identifiers</h2>
href="https://en.wikipedia.org/wiki/ASCII">ASCII</a> letters,
'<code>.</code>', '<code>-</code>' and '<code>_</code>'.
Do not use digits, as that might create an ambiguity with <a
href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX
href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX.1-2017
<code>TZ</code> strings</a>.
A file name component must not exceed 14 characters or start with
'<code>-</code>'.
@@ -362,6 +362,11 @@ <h2 id="naming">Timezone identifiers</h2>
but conforms to the older-version guidelines related to <abbr>ISO</abbr> 3166-1;
it lists only one country code per entry and unlike <code>zone1970.tab</code>
it can list names defined in <code>backward</code>.
Applications that process only timestamps from now on can instead use the file
<code>zonenow.tab</code>, which partitions the world more coarsely,
into regions where clocks agree now and in the predicted future;
this file is smaller and simpler than <code>zone1970.tab</code>
and <code>zone.tab</code>.
</p>

<p>
@@ -373,7 +378,7 @@ <h2 id="naming">Timezone identifiers</h2>
and no great weight should be attached to whether a link
is defined in <code>backward</code> or in some other file.
The source file <code>etcetera</code> defines names that may be useful
on platforms that do not support POSIX-style <code>TZ</code> strings;
on platforms that do not support POSIX.1-2017-style <code>TZ</code> strings;
no other source file other than <code>backward</code>
contains links to its zones.
One of <code>etcetera</code>'s names is <code>Etc/UTC</code>,
@@ -421,7 +426,7 @@ <h2 id="abbreviations">Time zone abbreviations</h2>
expression <code>[-+[:alnum:]]{3,6}</code> should match the
abbreviation.
This guarantees that all abbreviations could have been specified by a
POSIX <code>TZ</code> string.
POSIX.1-2017 <code>TZ</code> string.
</p>
</li>
<li>
@@ -765,12 +770,12 @@ <h2 id="accuracy">Accuracy of the <code><abbr>tz</abbr></code> database</h2>
calendar with 24-hour days. These divergences range from
relatively minor, such as Japanese bars giving times like "24:30" for the
wee hours of the morning, to more-significant differences such as <a
href="https://www.pri.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the
href="https://theworld.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the
east African practice of starting the day at dawn</a>, renumbering
the Western 06:00 to be 12:00. These practices are largely outside
the scope of the <code><abbr>tz</abbr></code> code and data, which
provide only limited support for date and time localization
such as that required by POSIX.
such as that required by POSIX.1-2017.
If <abbr>DST</abbr> is not used a different time zone
can often do the trick; for example, in Kenya a <code>TZ</code> setting
like <code>&lt;-03&gt;3</code> or <code>America/Cayenne</code> starts
@@ -867,23 +872,23 @@ <h2 id="functions">Time and date functions</h2>
an older <code>zic</code>.
</p>

<h3 id="POSIX">POSIX properties and limitations</h3>
<h3 id="POSIX">POSIX.1-2017 properties and limitations</h3>
<ul>
<li>
<p>
In POSIX, time display in a process is controlled by the
In POSIX.1-2017, time display in a process is controlled by the
environment variable <code>TZ</code>.
Unfortunately, the POSIX
Unfortunately, the POSIX.1-2017
<code>TZ</code> string takes a form that is hard to describe and
is error-prone in practice.
Also, POSIX <code>TZ</code> strings cannot deal with daylight
Also, POSIX.1-2017 <code>TZ</code> strings cannot deal with daylight
saving time rules not based on the Gregorian calendar (as in
Morocco), or with situations where more than two time zone
abbreviations or <abbr>UT</abbr> offsets are used in an area.
</p>

<p>
The POSIX <code>TZ</code> string takes the following form:
The POSIX.1-2017 <code>TZ</code> string takes the following form:
</p>

<p>
@@ -950,7 +955,7 @@ <h3 id="POSIX">POSIX properties and limitations</h3>
</dl>

<p>
Here is an example POSIX <code>TZ</code> string for New
Here is an example POSIX.1-2017 <code>TZ</code> string for New
Zealand after 2007.
It says that standard time (<abbr>NZST</abbr>) is 12 hours ahead
of <abbr>UT</abbr>, and that daylight saving time
@@ -961,7 +966,7 @@ <h3 id="POSIX">POSIX properties and limitations</h3>
<pre><code>TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'</code></pre>

<p>
This POSIX <code>TZ</code> string is hard to remember, and
This POSIX.1-2017 <code>TZ</code> string is hard to remember, and
mishandles some timestamps before 2008.
With this package you can use this instead:
</p>
@@ -999,7 +1004,7 @@ <h3 id="POSIX">POSIX properties and limitations</h3>
limit phone calls to off-peak hours.
</li>
<li>
POSIX provides no convenient and efficient way to determine
POSIX.1-2017 provides no convenient and efficient way to determine
the <abbr>UT</abbr> offset and time zone abbreviation of arbitrary
timestamps, particularly for timezones
that do not fit into the POSIX model.
@@ -1026,14 +1031,14 @@ <h3 id="POSIX">POSIX properties and limitations</h3>
</li>
</ul>

<h3 id="POSIX-extensions">Extensions to POSIX in the
<h3 id="POSIX-extensions">Extensions to POSIX.1-2017 in the
<code><abbr>tz</abbr></code> code</h3>
<ul>
<li>
<p>
The <code>TZ</code> environment variable is used in generating
the name of a file from which time-related information is read
(or is interpreted à la POSIX); <code>TZ</code> is no longer
(or is interpreted à la POSIX.1-2017); <code>TZ</code> is no longer
constrained to be a string containing abbreviations
and numeric data as described <a href="#POSIX">above</a>.
The file's format is <dfn><abbr>TZif</abbr></dfn>,
412 changes: 181 additions & 231 deletions tz-art.html

Large diffs are not rendered by default.

97 changes: 41 additions & 56 deletions tz-link.html
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ <h2 id="tzdb">The <code><abbr title="time zone">tz</abbr></code> database</h2>
and switched back in 2006.
To use the database on an extended <a
href="https://en.wikipedia.org/wiki/POSIX"><abbr
title="Portable Operating System Interface">POSIX</abbr></a>
title="Portable Operating System Interface">POSIX</abbr>.1-2017</a>
implementation set the <code><abbr>TZ</abbr></code>
environment variable to the location's full name,
e.g., <code><abbr>TZ</abbr>="America/New_York"</code>.</p>
@@ -172,7 +172,7 @@ <h2 id="download">Downloading the <code><abbr>tz</abbr></code> database</h2>
ustar interchange format</a>, compressed as described above;
older releases use a nearly compatible format.
Since version 2016h, each release has contained a text file named
"<samp>version</samp>" whose first (and currently only) line is the version.
"<code>version</code>" whose first (and currently only) line is the version.
Older releases are <a href="https://ftp.iana.org/tz/releases/">archived</a>,
and are also available in an
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
@@ -362,9 +362,6 @@ <h2 id="web">Web sites using recent versions of the
<li><a
href="https://www.convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current
Time in 1000 Places</a> uses descriptions of the values.</li>
<li><a href="https://home.kpn.nl/vanadovv/time/TZworld.html">Complete
timezone information for all countries</a>
displays tables of <abbr>DST</abbr> rules.
<li><a href="https://www.timeanddate.com/worldclock/">The World Clock &ndash;
Worldwide</a> lets you sort zone names and convert times.</li>
<li><a href="https://24timezones.com">24TimeZones</a> has a world
@@ -511,12 +508,12 @@ <h2 id="compilers">Other <code><abbr>tz</abbr></code> compilers</h2>
<li>Many modern
<a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>
runtimes support <code><abbr>tz</abbr></code> natively via the
<samp>timeZone</samp> option of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"><samp>Intl.DateTimeFormat</samp></a>.
<code>timeZone</code> option of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"><code>Intl.DateTimeFormat</code></a>.
This can be used as-is or with most of the following libraries,
many of which also support runtimes lacking the <samp>timeZone</samp> option.
many of which also support runtimes lacking the <code>timeZone</code> option.
<ul>
<li>The <a
href="https://github.com/formatjs/date-time-format-timezone"><samp>Intl.DateTimeFormat</samp>
href="https://github.com/formatjs/date-time-format-timezone"><code>Intl.DateTimeFormat</code>
timezone polyfill</a>
is freely available under a <abbr>BSD</abbr>-style license.</li>
<li>The <a href="https://date-fns.org/">date-fns</a>
@@ -529,7 +526,7 @@ <h2 id="compilers">Other <code><abbr>tz</abbr></code> compilers</h2>
manipulation library.
It is freely available under the <abbr>MIT</abbr> license.</li>
<li><a href="https://moment.github.io/luxon/">Luxon</a> improves
timezone support for the <samp>Intl</samp> API.
timezone support for the <code>Intl</code> API.
It is freely available under the <abbr>MIT</abbr> license.</li>
<li><a href="https://momentjs.com/timezone/">Moment Timezone</a> is a
Moment.js plugin.
@@ -550,11 +547,11 @@ <h2 id="compilers">Other <code><abbr>tz</abbr></code> compilers</h2>
It is freely available under the <abbr>MIT</abbr> license.</li>
</ul>
The proposed <a
href="https://github.com/tc39/proposal-temporal"><samp>Temporal</samp>
href="https://github.com/tc39/proposal-temporal"><code>Temporal</code>
objects</a> let programs access an abstract view of
<code><abbr>tzdb</abbr></code> data, and are designed to replace <a
href="https://codeofmatt.com/javascript-date-type-is-horribly-broken/">JavaScript's
problematic <samp>Date</samp> objects</a> when working with dates and times.
problematic <code>Date</code> objects</a> when working with dates and times.
<li><a href="https://github.com/JuliaTime/">JuliaTime</a> contains a
compiler from <code><abbr>tz</abbr></code> source into
<a href="https://julialang.org/">Julia</a>. It is freely available
@@ -620,6 +617,16 @@ <h2 id="TZif">Other <abbr>TZif</abbr> readers</h2>
library that translates between <abbr>UT</abbr> and civil time and
can read <abbr>TZif</abbr> files. It is freely available under the Apache
License.</li>
<li>The
<a href="https://github.com/nayarsystems/posix_tz_db"><code>posix_tz_db</code>
package</a> contains Python code
to generate <abbr>CSV</abbr> and <abbr>JSON</abbr> tables that map
<code><abbr>tz</abbr></code> settings to POSIX.1-2017-like approximations.
For example, it maps <code>"Africa/Cairo"</code>
to <code>"EET-2EEST,M4.5.5/0,M10.5.4/24"</code>,
an approximation valid for Cairo timestamps from 2023 on.
This can help porting to platforms that support only POSIX.1-2017.
The package is freely available under the MIT license.</li>
<li><a href="https://github.com/derickr/timelib">Timelib</a> is a C
library that reads <abbr>TZif</abbr> files and converts
timestamps from one time zone or format to another.
@@ -666,9 +673,7 @@ <h2 id="software">Other <code><abbr>tz</abbr></code>-based time zone software</h
<ul>
<li><a href="https://foxclocks.org">FoxClocks</a>
is an extension for <a href="https://www.google.com/chrome/">Google
Chrome</a> and for <a
href="https://wiki.mozilla.org/Modules/Toolkit">Mozilla
Toolkit</a> applications like <a
Chrome</a>, <a
href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> and <a
href="https://www.mozilla.org/en-US/thunderbird/">Thunderbird</a>.
It displays multiple clocks in the application window, and has a mapping
@@ -782,32 +787,9 @@ <h2 id="boundaries">Time zone boundaries</h2>
Its code is freely available under the <abbr>MIT</abbr> license, and
its data entries are freely available under the
<a href="https://opendatacommons.org/licenses/odbl/">Open Data Commons
Open Database License</a>. The maps' borders appear to be quite accurate.</li>
<li>Programmatic interfaces that map geographical coordinates via tz_world to
<code><abbr>tzdb</abbr></code> timezones include:
<ul>
<li><a href="https://github.com/mj1856/GeoTimeZone">GeoTimeZone</a> is
written in <a
href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a>
and is freely available under the <abbr>MIT</abbr> license.</li>
<li>The <a href="https://github.com/bradfitz/latlong">latlong package</a>
is written in Go and is freely available under the Apache License.</li>
<li><a href="https://github.com/drtimcooper/LatLongToTimezone">LatLongToTimezone</a>,
in both Java and
<a href="https://en.wikipedia.org/wiki/Swift_(programming_language)">Swift</a>
form, is freely available under the MIT license.</li>
<li>For Node.js,
the <a href="https://www.npmjs.com/package/geo-tz">geo-tz module</a>
is freely available under the MIT license, and
the <a href="https://www.npmjs.com/package/tz-lookup">tz-lookup module</a>
is in the public domain.</li>
<li>The <a
href="https://github.com/MrMinimal64/timezonefinder">timezonefinder</a>
library for Python is freely available under the MIT license.
<li>The <a
href="https://github.com/gunyarakun/timezone_finder">timezone_finder</a>
library for Ruby is freely available under the MIT license.</li>
</ul></li>
Open Database License</a>. The borders appear to be quite accurate.
Its main web page lists more than twenty libraries
for looking up a timezone name from a GPS coordinate.</li>
<li>Free access via a network API, if you register a key, is provided by
the <a
href="https://www.geonames.org/export/web-services.html#timezone">GeoNames
@@ -826,12 +808,9 @@ <h2 id="boundaries">Time zone boundaries</h2>
<li><a href="http://statoids.com/statoids.html">Administrative
Divisions of Countries ("Statoids")</a> lists
political subdivision data related to time zones.</li>
<li><a href="https://home.kpn.nl/vanadovv/time/Multizones.html">Time
zone boundaries for multizone countries</a> summarizes legal
boundaries between time zones within countries.</li>
<li><a href="https://manifold.net/info/freestuff.shtml">Manifold Software
&ndash; GIS and Database Tools</a> includes a Manifold-format map of
world time zone boundaries distributed under the
world time zone boundaries circa 2007, distributed under the
<abbr>GPL</abbr>.</li>
<li>A ship within the <a
href="https://en.wikipedia.org/wiki/Territorial_waters">territorial
@@ -862,7 +841,7 @@ <h2 id="civil">Civil time concepts and history</h2>
<li><a href="https://www.w3.org/TR/timezone/">Working with Time Zones</a>
contains guidelines and best practices for software applications that
deal with civil time.</li>
<li><a href="https://www.staff.science.uu.nl/~gent0113/idl/idl.htm">A History of
<li><a href="https://webspace.science.uu.nl/~gent0113/idl/idl.htm">A History of
the International Date Line</a> tells the story of the most important
time zone boundary.</li>
<li><a href="http://statoids.com/tconcept.html">Basic Time
@@ -875,17 +854,17 @@ <h2 id="national">National histories of legal time</h2>
<dl>
<dt>Australia</dt>
<dd>The Parliamentary Library commissioned a <a
href="https://www.aph.gov.au/binaries/library/pubs/rp/2009-10/10rp10.pdf">research
href="https://parlinfo.aph.gov.au/parlInfo/download/library/prspub/359V6/upload_binary/359v60.pdf">research
paper on daylight saving time in Australia</a>.
The Bureau of Meteorology publishes a list of <a
href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">Implementation
Dates of Daylight Savings Time within Australia</a>.</dd>
<dt>Belgium</dt>
<dd>The Royal Observatory of Belgium maintains a table of time in
Belgium (in
<a href="https://www.astro.oma.be/GENERAL/INFO/nli001a.html"
<a href="https://robinfo.oma.be/nl/astro-info/tijd/"
hreflang="nl">Dutch</a> and <a
href="https://www.astro.oma.be/GENERAL/INFO/fri001a.html"
href="https://robinfo.oma.be/fr/astro-info/heure/"
hreflang="fr">French</a>).</dd>
<dt>Brazil</dt>
<dd>The Time Service Department of the National Observatory
@@ -929,7 +908,7 @@ <h2 id="national">National histories of legal time</h2>
href="https://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm"
hreflang="es">history of Mexican local time (in Spanish)</a>.</dd>
<dt>Netherlands</dt>
<dd><a href="https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm"
<dd><a href="https://webspace.science.uu.nl/~gent0113/wettijd/wettijd.htm"
hreflang="nl">Legal time in the Netherlands (in Dutch)</a>
covers the history of local time in the Netherlands from ancient times.</dd>
<dt>New Zealand</dt>
@@ -938,7 +917,7 @@ <h2 id="national">National histories of legal time</h2>
Daylight Saving</a>.</dd>
<dt>Palestine</dt>
<dd>The Ministry of Telecom and IT publishes a <a
href="https://mtit.pna.ps/Site/TimeZoon"
href="https://mtit.pna.ps/home/TimeZone"
hreflang="ar">history of clock changes (in Arabic)</a>.</dd>
<dt>Portugal</dt>
<dd>The Lisbon Astronomical Observatory publishes a
@@ -986,14 +965,17 @@ <h2 id="costs">Costs and benefits of time shifts</h2>
shifts in time zones.</li>
<li>Havranek T, Herman D, Irsova D.
<a href="https://www.iaee.org/en/publications/ejarticle.aspx?id=3051">Does
daylight saving save electricity? A meta-analysis.</a>
daylight saving save electricity? A meta-analysis</a>.
<em>Energy J.</em> 2018;39(2):35&ndash;61.
doi:<a href="https://doi.org/10.5547/01956574.39.2.thav">10.5547/01956574.39.2.thav</a>.
This analyzes research literature and concludes, "Electricity savings
are larger for countries farther away from the equator, while
subtropical regions consume more electricity because of <abbr>DST</abbr>."</li>
<li>Malow BA. It is time to abolish the clock change and adopt permanent
standard time in the United States: a Sleep Research Society position statement.
<li>Malow BA. <a
href="https://academic.oup.com/sleep/article/45/12/zsac236/6717940">It is time
to abolish the clock change and adopt permanent
standard time in the United States:
a Sleep Research Society position statement</a>.
<em>Sleep.</em> 2022;45(12):zsac236.
doi:<a href="https://doi.org/10.1093/sleep/zsac236">10.1093/sleep/zsac236</a>.
After reviewing the scientific literature, the Sleep Research Society
@@ -1002,13 +984,13 @@ <h2 id="costs">Costs and benefits of time shifts</h2>
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.10898">Permanent standard time
is the optimal choice for health and safety:
an American Academy of Sleep Medicine position statement</a>.
<em>J Clin Sleep Med.</em> 2023-10-31.
<em>J Clin Sleep Med.</em> 2024;20(1):121&ndash;125.
doi:<a href="https://doi.org/10.5664/jcsm.10898">10.5664/jcsm.10898</a>.
The AASM argues for permanent standard time due to health and safety risks
and economic costs of both <abbr>DST</abbr> transitions and
permanent <abbr>DST</abbr>.</li>
<li>Roenneberg T, Wirz-Justice A, Skene DJ <em>et al</em>.
<a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7205184/">Why
<a href="https://journals.sagepub.com/doi/10.1177/0748730419854197">Why
should we abolish Daylight Saving Time?</a>
<em>J Biol Rhythms.</em> 2019;34(3):227&ndash;230.
doi:<a href="https://doi.org/10.1177/0748730419854197">10.1177/0748730419854197</a>.
@@ -1128,9 +1110,12 @@ <h2 id="precision">Precision timekeeping</h2>
without Leap Seconds</a> gives pointers on this
contentious issue.
The General Conference on Weights and Measures
<a href="https://www.bipm.org/en/cgpm-2022/resolution-4">voted in 2022</a>
<a href="https://www.bipm.org/en/cgpm-2022/resolution-4">decided in 2022</a>
to discontinue the use of leap seconds by 2035, replacing them with an
as-yet-undetermined scheme some time after the year 2135.
The World Radiocommunication Conference <a
href="https://www.itu.int/dms_pub/itu-r/opb/act/R-ACT-WRC.15-2023-PDF-E.pdf">resolved
in 2023</a> to cooperate with this process.
</li>
</ul>
</section>
28 changes: 15 additions & 13 deletions tzfile.5
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ described in the file is associated with the time period
starting with the same-indexed transition time
and continuing up to but not including the next transition time.
(The last time type is present only for consistency checking with the
POSIX-style TZ string described below.)
POSIX.1-2017-style TZ string described below.)
These values serve as indices into the next field.
.IP \(bu
.B tzh_typecnt
@@ -186,7 +186,8 @@ must also be set.
.PP
The standard/wall and UT/local indicators were designed for
transforming a TZif file's transition times into transitions appropriate
for another time zone specified via a POSIX-style TZ string that lacks rules.
for another time zone specified via
a POSIX.1-2017-style TZ string that lacks rules.
For example, when TZ="EET\*-2EEST" and there is no TZif file "EET\*-2EEST",
the idea was to adapt the transition times from a TZif file with the
well-known name "posixrules" that is present only for this purpose and
@@ -215,13 +216,14 @@ the above header and data are followed by a second header and data,
identical in format except that
eight bytes are used for each transition time or leap second time.
(Leap second counts remain four bytes.)
After the second header and data comes a newline-enclosed,
POSIX-TZ-environment-variable-style string for use in handling instants
After the second header and data comes a newline-enclosed string
in the style of the contents of a POSIX.1-2017 TZ environment variable,
for use in handling instants
after the last transition time stored in the file
or for all instants if the file has no transitions.
The POSIX-style TZ string is empty (i.e., nothing between the newlines)
if there is no POSIX-style representation for such instants.
If nonempty, the POSIX-style TZ string must agree with the local time
The TZ string is empty (i.e., nothing between the newlines)
if there is no POSIX.1-2017-style representation for such instants.
If nonempty, the TZ string must agree with the local time
type after the last transition time if present in the eight-byte data;
for example, given the string
.q "WET0WEST,M3.5.0/1,M10.5.0"
@@ -233,8 +235,8 @@ Also, if there is at least one transition, time type 0 is associated
with the time period from the indefinite past up to but not including
the earliest transition time.
.SS Version 3 format
For version-3-format timezone files, the POSIX-TZ-style string may
use two minor extensions to the POSIX TZ format, as described in
For version-3-format timezone files, the TZ string may
use two minor extensions to the POSIX.1-2017 TZ format, as described in
.BR newtzset (3).
First, the hours part of its transition times may be signed and range from
\-167 through 167 instead of the POSIX-required unsigned values
@@ -352,7 +354,7 @@ version 2+ data even if the reader's native timestamps have only
.IP \(bu
Some readers designed for version 2 might mishandle
timestamps after a version 3 or higher file's last transition, because
they cannot parse extensions to POSIX in the TZ-like string.
they cannot parse extensions to POSIX.1-2017 in the TZ-like string.
As a partial workaround, a writer can output more transitions
than necessary, so that only far-future timestamps are
mishandled by version 2 readers.
@@ -403,7 +405,7 @@ Some readers mishandle a transition if its timestamp has
the minimum possible signed 64-bit value.
Timestamps less than \-2**59 are not recommended.
.IP \(bu
Some readers mishandle POSIX-style TZ strings that
Some readers mishandle TZ strings that
contain
.q "<"
or
@@ -431,12 +433,12 @@ Some readers mishandle TZif files that specify
daylight-saving time UT offsets that are less than the UT
offsets for the corresponding standard time.
These readers do not support locations like Ireland, which
uses the equivalent of the POSIX TZ string
uses the equivalent of the TZ string
.q "IST\*-1GMT0,M10.5.0,M3.5.0/1",
observing standard time
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
As a partial workaround, a writer can output data for the
equivalent of the POSIX TZ string
equivalent of the TZ string
.q "GMT0IST,M3.5.0/1,M10.5.0",
thus swapping standard and daylight saving time.
Although this workaround misidentifies which part of the year
6 changes: 3 additions & 3 deletions tzfile.h
Original file line number Diff line number Diff line change
@@ -78,11 +78,11 @@ struct tzhead {
** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for
** such instants).
** (with nothing between the newlines if there is no POSIX.1-2017
** representation for such instants).
**
** If tz_version is '3' or greater, the above is extended as follows.
** First, the POSIX TZ string's hour offset may range from -167
** First, the TZ string's hour offset may range from -167
** through 167 as compared to the POSIX-required 0 through 24.
** Second, its DST start time may be January 1 at 00:00 and its stop
** time December 31 at 24:00 plus the difference between DST and
43 changes: 28 additions & 15 deletions tzselect.ksh
Original file line number Diff line number Diff line change
@@ -40,9 +40,13 @@ REPORT_BUGS_TO=tz@iana.org
# The substr avoids problems when VALUE is of the form X=Y and would be
# misinterpreted as an assignment.

# This script does not want path expansion.
set -f

# Specify default values for environment variables if they are unset.
: ${AWK=awk}
: ${TZDIR=`pwd`}
: ${PWD=`pwd`}
: ${TZDIR=$PWD}

# Output one argument as-is to standard output, with trailing newline.
# Safer than 'echo', which can mishandle '\' or leading '-'.
@@ -113,7 +117,8 @@ then
else
doselect() {
# Field width of the prompt numbers.
select_width=`expr $# : '.*'`
print_nargs_length="BEGIN {print length(\"$#\");}"
select_width=`$AWK "$print_nargs_length"`

select_i=

@@ -124,14 +129,14 @@ else
select_i=0
for select_word
do
select_i=`expr $select_i + 1`
select_i=`$AWK "BEGIN { print $select_i + 1 }"`
printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word"
done;;
*[!0-9]*)
echo >&2 'Please enter a number in range.';;
*)
if test 1 -le $select_i && test $select_i -le $#; then
shift `expr $select_i - 1`
shift `$AWK "BEGIN { print $select_i - 1 }"`
select_result=$1
break
fi
@@ -165,7 +170,7 @@ do
esac
done

shift `expr $OPTIND - 1`
shift `$AWK "BEGIN { print $OPTIND - 1 }"`
case $# in
0) ;;
*) say >&2 "$0: $1: unknown argument"; exit 1
@@ -433,13 +438,18 @@ while
eval '
doselect '"$quoted_continents"' \
"coord - I want to use geographical coordinates." \
"TZ - I want to specify the timezone using the POSIX TZ format." \
"TZ - I want to specify the timezone using a POSIX.1-2017 TZ string." \
"time - I know local time already." \
"now - Like \"time\", but configure only for timestamps from now on."
continent=$select_result
case $continent in
Americas) continent=America;;
*" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
*)
# Get the first word of $continent. Path expansion is disabled
# so this works even with "*", which should not happen.
IFS=" "
for continent in $continent ""; do break; done
IFS=$newline;;
esac
case $zonetabtype,$continent in
zonenow,*) ;;
@@ -452,7 +462,7 @@ while

case $continent in
TZ)
# Ask the user for a POSIX TZ string. Check that it conforms.
# Ask the user for a POSIX.1-2017 TZ string. Check that it conforms.
check_POSIX_TZ_string='
BEGIN {
tz = substr(ARGV[1], 2)
@@ -482,7 +492,7 @@ while
read tz
$AWK "$check_POSIX_TZ_string" ="$tz"
do
say >&2 "'$tz' is not a conforming POSIX timezone string."
say >&2 "'$tz' is not a conforming POSIX.1-2017 timezone string."
done
TZ_for_date=$tz;;
*)
@@ -502,7 +512,7 @@ while
"$output_distances_or_times" \
="$coord" ="$TZ_COUNTRY_TABLE" ="$TZ_ZONE_TABLE" |
sort -n |
sed "${location_limit}q"
$AWK "{print} NR == $location_limit { exit }"
`
regions=`
$AWK '
@@ -746,15 +756,18 @@ while
do
TZdate=`LANG=C TZ="$TZ_for_date" date`
UTdate=`LANG=C TZ=UTC0 date`
TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'`
UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'`
case $TZsec in
$UTsec)
if $AWK '
function getsecs(d) {
return match(d, /.*:[0-5][0-9]/) ? substr(d, RLENGTH - 1, 2) : ""
}
BEGIN { exit getsecs(ARGV[1]) != getsecs(ARGV[2]) }
' ="$TZdate" ="$UTdate"
then
extra_info="
Selected time is now: $TZdate.
Universal Time is now: $UTdate."
break
esac
fi
done


23 changes: 7 additions & 16 deletions zic.8
Original file line number Diff line number Diff line change
@@ -171,7 +171,7 @@ boundaries, particularly if
causes a TZif file to contain explicit entries for
.RI pre- hi
transitions rather than concisely representing them
with an extended POSIX TZ string.
with an extended POSIX.1-2017 TZ string.
Also see the
.B "\*-b slim"
option for another way to shrink output size.
@@ -181,10 +181,10 @@ Generate redundant trailing explicit transitions for timestamps
that occur less than
.I hi
seconds since the Epoch, even though the transitions could be
more concisely represented via the extended POSIX TZ string.
more concisely represented via the extended POSIX.1-2017 TZ string.
This option does not affect the represented timestamps.
Although it accommodates nonstandard TZif readers
that ignore the extended POSIX TZ string,
that ignore the extended POSIX.1-2017 TZ string,
it increases the size of the altered output files.
.TP
.BI "\*-t " file
@@ -245,10 +245,10 @@ for
.PP
The output file does not contain all the information about the
long-term future of a timezone, because the future cannot be summarized as
an extended POSIX TZ string. For example, as of 2023 this problem
an extended POSIX.1-2017 TZ string. For example, as of 2023 this problem
occurs for Morocco's daylight-saving rules, as these rules are based
on predictions for when Ramadan will be observed, something that
an extended POSIX TZ string cannot represent.
an extended POSIX.1-2017 TZ string cannot represent.
.PP
The output contains data that may not be handled properly by client
code designed for older
@@ -360,24 +360,15 @@ an unquoted name should not contain characters from the set
Gives the first year in which the rule applies.
Any signed integer year can be supplied; the proleptic Gregorian calendar
is assumed, with year 0 preceding year 1.
The word
.B minimum
(or an abbreviation) means the indefinite past.
The word
.B maximum
(or an abbreviation) means the indefinite future.
Rules can describe times that are not representable as time values,
with the unrepresentable times ignored; this allows rules to be portable
among hosts with differing time value types.
.TP
.B TO
Gives the final year in which the rule applies.
In addition to
.B minimum
and
The word
.B maximum
(as above),
the word
(or an abbreviation) means the indefinite future, and the word
.B only
(or an abbreviation)
may be used to repeat the value of the
71 changes: 19 additions & 52 deletions zic.c
Original file line number Diff line number Diff line change
@@ -35,6 +35,9 @@ static zic_t const
# define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */

/* Minimum and maximum years, assuming signed 32-bit time_t. */
enum { YEAR_32BIT_MIN = 1901, YEAR_32BIT_MAX = 2038 };

/* An upper bound on how much a format might grow due to concatenation. */
enum { FORMAT_LEN_GROWTH_BOUND = 5 };

@@ -93,7 +96,6 @@ struct rule {

zic_t r_loyear; /* for example, 1986 */
zic_t r_hiyear; /* for example, 1986 */
bool r_lowasnum;
bool r_hiwasnum;

int r_month; /* 0..11 */
@@ -328,7 +330,7 @@ enum {
*/

enum {
YR_MINIMUM,
YR_MINIMUM, /* "minimum" is for backward compatibility only */
YR_MAXIMUM,
YR_ONLY
};
@@ -412,12 +414,10 @@ static struct lookup const lasts[] = {

static struct lookup const begin_years[] = {
{ "minimum", YR_MINIMUM },
{ "maximum", YR_MAXIMUM },
{ NULL, 0 }
};

static struct lookup const end_years[] = {
{ "minimum", YR_MINIMUM },
{ "maximum", YR_MAXIMUM },
{ "only", YR_ONLY },
{ NULL, 0 }
@@ -2187,13 +2187,12 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
*/
cp = loyearp;
lp = byword(cp, begin_years);
rp->r_lowasnum = lp == NULL;
if (!rp->r_lowasnum) switch (lp->l_value) {
if (lp) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_loyear = ZIC_MAX;
warning(_("FROM year \"%s\" is obsolete;"
" treated as %d"),
cp, YEAR_32BIT_MIN - 1);
rp->r_loyear = YEAR_32BIT_MIN - 1;
break;
default: unreachable();
} else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) {
@@ -2204,9 +2203,6 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
lp = byword(cp, end_years);
rp->r_hiwasnum = lp == NULL;
if (!rp->r_hiwasnum) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_hiyear = ZIC_MAX;
break;
@@ -2986,7 +2982,7 @@ rule_cmp(struct rule const *a, struct rule const *b)
return a->r_dayofmonth - b->r_dayofmonth;
}

/* Store into RESULT a POSIX TZ string that represent the future
/* Store into RESULT a POSIX.1-2017 TZ string that represent the future
predictions for the zone ZPFIRST with ZONECOUNT entries. Return a
compatibility indicator (a TZDB release year) if successful, a
negative integer if no such TZ string exissts. */
@@ -3125,7 +3121,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
register char * envvar;
register int max_abbr_len;
register int max_envvar_len;
register bool prodstic; /* all rules are min to max */
register int compat;
register bool do_extend;
register char version;
@@ -3151,7 +3146,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
timecnt = 0;
typecnt = 0;
charcnt = 0;
prodstic = zonecount == 1;
/*
** Thanks to Earl Chew
** for noting the need to unconditionally initialize startttisstd.
@@ -3169,12 +3163,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
updateminmax(zp->z_untilrule.r_loyear);
for (j = 0; j < zp->z_nrules; ++j) {
struct rule *rp = &zp->z_rules[j];
if (rp->r_lowasnum)
updateminmax(rp->r_loyear);
updateminmax(rp->r_loyear);
if (rp->r_hiwasnum)
updateminmax(rp->r_hiyear);
if (rp->r_lowasnum || rp->r_hiwasnum)
prodstic = false;
}
}
/*
@@ -3186,7 +3177,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (noise) {
if (!*envvar)
warning("%s %s",
_("no POSIX environment variable for zone"),
_("no POSIX.1-2017 environment variable"
" for zone"),
zpfirst->z_name);
else if (compat != 0) {
/* Circa-COMPAT clients, and earlier clients, might
@@ -3198,48 +3190,23 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
}
}
if (do_extend) {
/*
** Search through a couple of extra years past the obvious
** 400, to avoid edge cases. For example, suppose a non-POSIX
** rule applies from 2012 onwards and has transitions in March
** and September, plus some one-off transitions in November
** 2013. If zic looked only at the last 400 years, it would
** set max_year=2413, with the intent that the 400 years 2014
** through 2413 will be repeated. The last transition listed
** in the tzfile would be in 2413-09, less than 400 years
** after the last one-off transition in 2013-11. Two years
** might be overkill, but with the kind of edge cases
** available we're not sure that one year would suffice.
*/
enum { years_of_observations = YEARSPERREPEAT + 2 };

if (min_year >= ZIC_MIN + years_of_observations)
min_year -= years_of_observations;
else min_year = ZIC_MIN;
if (max_year <= ZIC_MAX - years_of_observations)
max_year += years_of_observations;
else max_year = ZIC_MAX;
/*
** Regardless of any of the above,
** for a "proDSTic" zone which specifies that its rules
** always have and always will be in effect,
** we only need one cycle to define the zone.
*/
if (prodstic) {
min_year = 1900;
max_year = min_year + years_of_observations;
}
}
max_year = max(max_year, (redundant_time / (SECSPERDAY * DAYSPERNYEAR)
+ EPOCH_YEAR + 1));
max_year0 = max_year;
if (want_bloat()) {
/* For the benefit of older systems,
generate data from 1900 through 2038. */
if (min_year > 1900)
min_year = 1900;
if (max_year < 2038)
max_year = 2038;
if (min_year > YEAR_32BIT_MIN - 1)
min_year = YEAR_32BIT_MIN - 1;
if (max_year < YEAR_32BIT_MAX)
max_year = YEAR_32BIT_MAX;
}

if (min_time < lo_time || hi_time < max_time)
@@ -3474,8 +3441,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
}
if (do_extend) {
/*
** If we're extending the explicitly listed observations
** for 400 years because we can't fill the POSIX-TZ field,
** If we're extending the explicitly listed observations for
** 400 years because we can't fill the POSIX.1-2017 TZ field,
** check whether we actually ended up explicitly listing
** observations through that period. If there aren't any
** near the end of the 400-year period, add a redundant
98 changes: 65 additions & 33 deletions zishrink.awk
Original file line number Diff line number Diff line change
@@ -162,7 +162,7 @@ function make_line(n, field, \
# Process the input line LINE and save it for later output.

function process_input_line(line, \
f, field, end, i, n, r, startdef, \
f, field, end, n, outline, r, \
linkline, ruleline, zoneline)
{
# Remove comments, normalize spaces, and append a space to each line.
@@ -199,8 +199,10 @@ function process_input_line(line, \
}

# Abbreviate "max", "min", "only" and month names.
gsub(/ max /, " ma ", line)
gsub(/ min /, " mi ", line)
# Although "max" and "min" can both be abbreviated to just "m",
# the longer forms "ma" and "mi" are needed with zic 2023d and earlier.
gsub(/ max /, dataform == "vanguard" ? " m " : " ma ", line)
gsub(/ min /, dataform == "vanguard" ? " m " : " mi ", line)
gsub(/ only /, " o ", line)
gsub(/ Jan /, " Ja ", line)
gsub(/ Feb /, " F ", line)
@@ -234,66 +236,96 @@ function process_input_line(line, \
rule_used[r] = 1
}

# If this zone supersedes an earlier one, delete the earlier one
# from the saved output lines.
startdef = ""
if (zoneline)
zonename = startdef = field[2]
else if (linkline)
zonename = startdef = field[3]
else if (ruleline)
zonename = ""
if (startdef) {
i = zonedef[startdef]
if (i) {
do
output_line[i - 1] = ""
while (output_line[i++] ~ /^[-+0-9]/);
}
}
zonedef[zonename] = nout + 1

# Save the line for later output.
output_line[nout++] = make_line(n, field)
# Save the information for later output.
outline = make_line(n, field)
if (ruleline)
rule_output_line[nrule_out++] = outline
else if (linkline) {
# In vanguard format with Gawk, links are output sorted by destination.
if (dataform == "vanguard" && PROCINFO["version"])
linkdef[zonename] = field[2]
else
link_output_line[nlink_out++] = outline
}else
zonedef[zonename] = (zoneline ? "" : zonedef[zonename] "\n") outline
}

function omit_unused_rules( \
i, field)
{
for (i = 0; i < nout; i++) {
split(output_line[i], field)
if (field[1] == "R" && !rule_used[field[2]]) {
output_line[i] = ""
}
for (i = 0; i < nrule_out; i++) {
split(rule_output_line[i], field)
if (!rule_used[field[2]])
rule_output_line[i] = ""
}
}

function abbreviate_rule_names( \
abbr, f, field, i, n, r)
abbr, f, field, i, n, newdef, newline, r, \
zoneline, zonelines, zonename)
{
for (i = 0; i < nout; i++) {
n = split(output_line[i], field)
for (i = 0; i < nrule_out; i++) {
n = split(rule_output_line[i], field)
if (n) {
f = field[1] == "Z" ? 4 : field[1] == "L" ? 0 : 2
r = field[f]
r = field[2]
if (r ~ /^[^-+0-9]/) {
abbr = rule[r]
if (!abbr) {
rule[r] = abbr = gen_rule_name(r)
}
field[f] = abbr
output_line[i] = make_line(n, field)
field[2] = abbr
rule_output_line[i] = make_line(n, field)
}
}
}
for (zonename in zonedef) {
zonelines = split(zonedef[zonename], zoneline, /\n/)
newdef = ""
for (i = 1; i <= zonelines; i++) {
newline = zoneline[i]
n = split(newline, field)
f = i == 1 ? 4 : 2
r = rule[field[f]]
if (r) {
field[f] = r
newline = make_line(n, field)
}
newdef = (newdef ? newdef "\n" : "") newline
}
zonedef[zonename] = newdef
}
}

function output_saved_lines( \
i)
i, zonename)
{
for (i = 0; i < nout; i++)
if (output_line[i])
print output_line[i]
for (i = 0; i < nrule_out; i++)
if (rule_output_line[i])
print rule_output_line[i]

# When using gawk, output zones sorted by name.
# This makes the output a bit more compressible.
PROCINFO["sorted_in"] = "@ind_str_asc"
for (zonename in zonedef)
print zonedef[zonename]

if (nlink_out)
for (i = 0; i < nlink_out; i++)
print link_output_line[i]
else {
# When using gawk, output links sorted by destination.
# This also helps compressibility a bit.
PROCINFO["sorted_in"] = "@val_type_asc"
for (zonename in linkdef)
printf "L %s %s\n", linkdef[zonename], zonename
}
}

BEGIN {
4 changes: 3 additions & 1 deletion zonenow.tab
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ XX +2518+05518 Asia/Dubai Russia; Caucasus; Persian Gulf; Seychelles; Réunion
XX +3431+06912 Asia/Kabul Afghanistan
#
# +05
XX +4120+06918 Asia/Tashkent Russia; Tajikistan; Turkmenistan; Uzbekistan; Maldives
XX +4120+06918 Asia/Tashkent Russia; west Kazakhstan; Tajikistan; Turkmenistan; Uzbekistan; Maldives
#
# +05 - PKT
XX +2452+06703 Asia/Karachi Pakistan ("PKT")
@@ -215,6 +215,8 @@ XX +2743+08519 Asia/Kathmandu Nepal
#
# +06
XX +2343+09025 Asia/Dhaka Russia; Kyrgyzstan; Bhutan; Bangladesh; Chagos
# +06 until 2024-03-01; then +05
XX +4315+07657 Asia/Almaty Kazakhstan (except western areas)
#
# +06:30
XX +1647+09610 Asia/Yangon Myanmar; Cocos